From d95b2efabbe284ba1450a7f059864abb61822abe Mon Sep 17 00:00:00 2001 From: bobhancockg <108475962+bobhancockg@users.noreply.github.com> Date: Fri, 4 Nov 2022 11:41:41 -0400 Subject: [PATCH] Changes for release 12_0. (#716) --- ChangeLog | 10 + .../approve_merchant_center_link.py | 2 +- .../account_management/create_customer.py | 2 +- .../get_account_hierarchy.py | 2 +- .../get_account_information.py | 2 +- .../account_management/get_change_details.py | 2 +- .../account_management/get_change_summary.py | 2 +- .../get_pending_invitations.py | 2 +- .../invite_user_with_access_role.py | 2 +- .../link_manager_to_client.py | 10 +- .../list_accessible_customers.py | 2 +- .../reject_merchant_center_link.py | 2 +- .../account_management/update_user_access.py | 2 +- .../advanced_operations/add_ad_customizer.py | 8 +- .../add_ad_group_bid_modifier.py | 2 +- .../advanced_operations/add_app_campaign.py | 6 +- .../add_bidding_data_exclusion.py | 2 +- .../add_bidding_seasonality_adjustment.py | 2 +- examples/advanced_operations/add_call_ad.py | 2 +- .../add_display_upload_ad.py | 2 +- .../add_dynamic_page_feed_asset.py | 276 -- .../add_dynamic_search_ads.py | 2 +- .../advanced_operations/add_local_campaign.py | 364 -- .../add_performance_max_campaign.py | 2 +- ...responsive_search_ad_with_ad_customizer.py | 6 +- .../advanced_operations/add_smart_campaign.py | 89 +- .../add_smart_display_ad.py | 379 -- .../create_and_attach_shared_keyword_set.py | 2 +- ...ind_and_remove_criteria_from_shared_set.py | 2 +- .../get_ad_group_bid_modifiers.py | 2 +- .../use_cross_account_bidding_strategy.py | 2 +- .../use_portfolio_bidding_strategy.py | 2 +- examples/basic_operations/add_ad_groups.py | 2 +- examples/basic_operations/add_campaigns.py | 2 +- examples/basic_operations/add_keywords.py | 2 +- .../add_responsive_search_ad.py | 2 +- examples/basic_operations/get_ad_groups.py | 2 +- examples/basic_operations/get_campaigns.py | 2 +- .../basic_operations/get_expanded_text_ads.py | 2 +- examples/basic_operations/get_keywords.py | 2 +- .../get_responsive_search_ads.py | 2 +- examples/basic_operations/pause_ad.py | 2 +- examples/basic_operations/remove_ad.py | 2 +- examples/basic_operations/remove_ad_group.py | 2 +- examples/basic_operations/remove_campaign.py | 2 +- examples/basic_operations/remove_keyword.py | 2 +- .../search_for_google_ads_fields.py | 2 +- examples/basic_operations/update_ad_group.py | 2 +- examples/basic_operations/update_campaign.py | 2 +- examples/basic_operations/update_keyword.py | 2 +- .../update_responsive_search_ad.py | 2 +- .../billing/add_account_budget_proposal.py | 2 +- examples/billing/add_billing_setup.py | 2 +- .../billing/get_account_budget_proposals.py | 2 +- examples/billing/get_account_budgets.py | 2 +- examples/billing/get_billing_setup.py | 2 +- examples/billing/get_invoices.py | 2 +- examples/billing/remove_billing_setup.py | 2 +- .../add_campaign_bid_modifier.py | 2 +- .../campaign_management/add_campaign_draft.py | 2 +- .../add_campaign_labels.py | 2 +- .../add_complete_campaigns_using_batch_job.py | 2 +- .../campaign_management/create_experiment.py | 10 +- .../get_all_disapproved_ads.py | 2 +- .../get_campaigns_by_label.py | 2 +- .../campaign_management/set_ad_parameters.py | 6 +- .../update_campaign_criterion_bid_modifier.py | 2 +- examples/campaign_management/validate_ad.py | 2 +- .../get_campaigns.py | 5 +- .../handle_keyword_policy_violations.py | 2 +- .../error_handling/handle_partial_failure.py | 2 +- .../handle_rate_exceeded_error.py | 2 +- ...responsive_search_ad_policy_violations.py} | 131 +- .../add_affiliate_location_extensions.py | 2 +- ...dd_business_profile_location_extensions.py | 2 +- examples/extensions/add_call.py | 2 +- examples/extensions/add_geo_target.py | 2 +- examples/extensions/add_hotel_callout.py | 2 +- examples/extensions/add_image_extension.py | 2 +- .../extensions/add_lead_form_extension.py | 2 +- examples/extensions/add_prices.py | 2 +- examples/extensions/add_sitelinks.py | 2 +- .../extensions/add_sitelinks_using_assets.py | 6 +- .../migrate_promotion_feed_to_asset.py | 10 +- ...ire_sitelink_campaign_extension_setting.py | 2 +- examples/extensions/update_sitelink.py | 2 +- ...ate_sitelink_campaign_extension_setting.py | 2 +- examples/feeds/create_feed_item_set.py | 2 +- .../feeds/get_feed_items_of_feed_item_set.py | 2 +- examples/feeds/link_feed_item_set.py | 2 +- examples/feeds/remove_feed_items.py | 2 +- ...emove_flights_feed_item_attribute_value.py | 6 +- ...lights_feed_item_string_attribute_value.py | 2 +- examples/hotel_ads/add_hotel_ad.py | 2 +- .../add_hotel_ad_group_bid_modifiers.py | 2 +- .../hotel_ads/add_hotel_listing_group_tree.py | 2 +- .../migration/campaign_management/README.md | 36 - ...eate_complete_campaign_adwords_api_only.py | 251 -- ...ate_complete_campaign_both_apis_phase_1.py | 311 -- ...ate_complete_campaign_both_apis_phase_2.py | 349 -- ...ate_complete_campaign_both_apis_phase_3.py | 377 -- ...ate_complete_campaign_both_apis_phase_4.py | 439 -- ...te_complete_campaign_googleads_api_only.py | 497 --- .../campaign_management/requirements.txt | 31 - .../campaign_report_to_csv.py | 105 +- examples/misc/get_all_image_assets.py | 2 +- examples/misc/get_all_videos_and_images.py | 2 +- ...gate_search_result_pages_caching_tokens.py | 2 +- examples/misc/set_custom_client_timeouts.py | 2 +- examples/misc/upload_image.py | 2 +- examples/misc/upload_image_asset.py | 2 +- examples/misc/upload_media_bundle.py | 2 +- examples/planning/add_keyword_plan.py | 2 +- examples/planning/forecast_reach.py | 61 +- .../planning/generate_forecast_metrics.py | 2 +- examples/planning/generate_keyword_ideas.py | 2 +- ..._ad_group_criterion_cpc_bid_simulations.py | 2 +- ...aign_criterion_bid_modifier_simulations.py | 2 +- .../recommendations/apply_recommendation.py | 2 +- .../detect_and_apply_recommendations.py | 2 +- .../recommendations/dismiss_recommendation.py | 2 +- .../get_text_ad_recommendations.py | 2 +- .../add_combined_rule_user_list.py | 2 +- examples/remarketing/add_conversion_action.py | 2 +- .../add_conversion_based_user_list.py | 2 +- examples/remarketing/add_custom_audience.py | 2 +- .../add_customer_match_user_list.py | 2 +- .../add_dynamic_remarketing_asset.py | 2 +- .../add_expression_rule_user_list.py | 2 +- examples/remarketing/add_flights_feed.py | 2 +- examples/remarketing/add_logical_user_list.py | 2 +- ...ant_center_dynamic_remarketing_campaign.py | 6 +- examples/remarketing/add_real_estate_feed.py | 2 +- .../remarketing/add_remarketing_action.py | 2 +- .../set_up_advanced_remarketing.py | 2 +- examples/remarketing/set_up_remarketing.py | 2 +- .../update_audience_target_restriction.py | 2 +- .../remarketing/upload_call_conversion.py | 2 +- .../upload_conversion_adjustment.py | 2 +- .../upload_conversion_enhancement.py | 2 +- .../upload_conversion_with_identifiers.py | 2 +- .../remarketing/upload_offline_conversion.py | 2 +- .../upload_store_sales_transactions.py | 6 +- .../reporting/get_hotel_ads_performance.py | 2 +- examples/reporting/get_keyword_stats.py | 2 +- .../reporting/parallel_report_download.py | 2 +- examples/shopping_ads/add_listing_scope.py | 2 +- ...formance_max_product_listing_group_tree.py | 71 +- .../add_performance_max_retail_campaign.py | 114 +- .../shopping_ads/add_shopping_product_ad.py | 2 +- ...add_shopping_product_listing_group_tree.py | 2 +- .../shopping_ads/add_shopping_smart_ad.py | 377 -- .../get_product_bidding_category_constant.py | 2 +- .../add_campaign_targeting_criteria.py | 2 +- .../add_customer_negative_criteria.py | 2 +- .../add_demographic_targeting_criteria.py | 2 +- .../get_campaign_targeting_criteria.py | 2 +- .../get_geo_target_constants_by_names.py | 2 +- ...arch_for_language_and_carrier_constants.py | 2 +- google/ads/googleads/client.py | 2 +- google/ads/googleads/v12/__init__.py | 1805 ++++++++ google/ads/googleads/v12/common/__init__.py | 300 ++ .../googleads/v12/common/services/__init__.py | 15 + .../googleads/v12/common/types/__init__.py | 15 + .../googleads/v12/common/types/ad_asset.py | 128 + .../v12/common/types/ad_type_infos.py | 1249 ++++++ .../v12/common/types/asset_policy.py | 59 + .../v12/common/types/asset_set_types.py | 301 ++ .../googleads/v12/common/types/asset_types.py | 1559 +++++++ .../googleads/v12/common/types/asset_usage.py | 48 + .../googleads/v12/common/types/audiences.py | 378 ++ .../ads/googleads/v12/common/types/bidding.py | 334 ++ .../v12/common/types/click_location.py | 64 + .../googleads/v12/common/types/criteria.py | 1477 +++++++ .../types/criterion_category_availability.py | 141 + .../v12/common/types/custom_parameter.py | 45 + .../v12/common/types/customizer_value.py | 51 + .../ads/googleads/v12/common/types/dates.py | 81 + .../types/explorer_auto_optimizer_setting.py | 41 + .../googleads/v12/common/types/extensions.py | 635 +++ .../googleads/v12/common/types/feed_common.py | 45 + .../types/feed_item_set_filter_type_infos.py | 90 + .../v12/common/types/final_app_url.py | 57 + .../v12/common/types/frequency_cap.py | 90 + .../v12/common/types/keyword_plan_common.py | 262 ++ .../v12/common/types/matching_function.py | 234 ++ .../googleads/v12/common/types/metric_goal.py | 53 + .../ads/googleads/v12/common/types/metrics.py | 1389 +++++++ .../v12/common/types/offline_user_data.py | 565 +++ .../ads/googleads/v12/common/types/policy.py | 402 ++ .../v12/common/types/policy_summary.py | 59 + .../common/types/real_time_bidding_setting.py | 41 + .../googleads/v12/common/types/segments.py | 774 ++++ .../googleads/v12/common/types/simulation.py | 649 +++ .../googleads/v12/common/types/tag_snippet.py | 68 + .../v12/common/types/targeting_setting.py | 112 + .../googleads/v12/common/types/text_label.py | 48 + .../v12/common/types/url_collection.py | 51 + .../googleads/v12/common/types/user_lists.py | 576 +++ .../ads/googleads/v12/common/types/value.py | 66 + google/ads/googleads/v12/enums/__init__.py | 319 ++ .../googleads/v12/enums/services/__init__.py | 15 + .../ads/googleads/v12/enums/types/__init__.py | 15 + .../enums/types/access_invitation_status.py | 41 + .../v12/enums/types/access_reason.py | 43 + .../googleads/v12/enums/types/access_role.py | 40 + .../types/account_budget_proposal_status.py | 41 + .../types/account_budget_proposal_type.py | 40 + .../v12/enums/types/account_budget_status.py | 39 + .../v12/enums/types/account_link_status.py | 46 + .../types/ad_customizer_placeholder_field.py | 40 + .../v12/enums/types/ad_destination_type.py | 47 + .../enums/types/ad_group_ad_rotation_mode.py | 40 + .../v12/enums/types/ad_group_ad_status.py | 41 + .../ad_group_criterion_approval_status.py | 42 + .../enums/types/ad_group_criterion_status.py | 39 + .../v12/enums/types/ad_group_status.py | 41 + .../v12/enums/types/ad_group_type.py | 55 + .../v12/enums/types/ad_network_type.py | 42 + .../types/ad_serving_optimization_status.py | 41 + .../googleads/v12/enums/types/ad_strength.py | 42 + .../ads/googleads/v12/enums/types/ad_type.py | 65 + .../types/advertising_channel_sub_type.py | 53 + .../enums/types/advertising_channel_type.py | 47 + ...filiate_location_feed_relationship_type.py | 41 + .../affiliate_location_placeholder_field.py | 47 + .../v12/enums/types/age_range_type.py | 47 + .../v12/enums/types/app_campaign_app_store.py | 38 + ...app_campaign_bidding_strategy_goal_type.py | 44 + .../v12/enums/types/app_payment_model_type.py | 37 + .../v12/enums/types/app_placeholder_field.py | 44 + .../googleads/v12/enums/types/app_store.py | 40 + .../types/app_url_operating_system_type.py | 38 + .../v12/enums/types/asset_field_type.py | 63 + .../v12/enums/types/asset_group_status.py | 41 + .../v12/enums/types/asset_link_status.py | 41 + .../enums/types/asset_performance_label.py | 45 + .../v12/enums/types/asset_set_asset_status.py | 40 + .../v12/enums/types/asset_set_link_status.py | 42 + .../v12/enums/types/asset_set_status.py | 40 + .../v12/enums/types/asset_set_type.py | 50 + .../googleads/v12/enums/types/asset_source.py | 40 + .../googleads/v12/enums/types/asset_type.py | 62 + .../v12/enums/types/async_action_status.py | 43 + .../v12/enums/types/attribution_model.py | 49 + .../types/audience_insights_dimension.py | 48 + .../v12/enums/types/audience_status.py | 38 + .../v12/enums/types/batch_job_status.py | 39 + .../v12/enums/types/bid_modifier_source.py | 38 + .../v12/enums/types/bidding_source.py | 42 + .../enums/types/bidding_strategy_status.py | 38 + .../types/bidding_strategy_system_status.py | 61 + .../v12/enums/types/bidding_strategy_type.py | 55 + .../v12/enums/types/billing_setup_status.py | 40 + .../enums/types/brand_safety_suitability.py | 41 + .../budget_campaign_association_status.py | 42 + .../v12/enums/types/budget_delivery_method.py | 40 + .../v12/enums/types/budget_period.py | 38 + .../v12/enums/types/budget_status.py | 38 + .../googleads/v12/enums/types/budget_type.py | 40 + .../types/call_conversion_reporting_state.py | 41 + .../v12/enums/types/call_placeholder_field.py | 41 + .../v12/enums/types/call_to_action_type.py | 45 + .../types/call_tracking_display_location.py | 40 + .../googleads/v12/enums/types/call_type.py | 40 + .../enums/types/callout_placeholder_field.py | 37 + .../enums/types/campaign_criterion_status.py | 39 + .../v12/enums/types/campaign_draft_status.py | 43 + .../enums/types/campaign_experiment_type.py | 41 + .../v12/enums/types/campaign_group_status.py | 38 + .../enums/types/campaign_primary_status.py | 51 + .../types/campaign_primary_status_reason.py | 74 + .../enums/types/campaign_serving_status.py | 41 + .../enums/types/campaign_shared_set_status.py | 40 + .../v12/enums/types/campaign_status.py | 41 + .../enums/types/chain_relationship_type.py | 40 + .../v12/enums/types/change_client_type.py | 50 + .../enums/types/change_event_resource_type.py | 59 + .../enums/types/change_status_operation.py | 41 + .../types/change_status_resource_type.py | 56 + .../googleads/v12/enums/types/click_type.py | 90 + .../enums/types/combined_audience_status.py | 38 + .../v12/enums/types/content_label_type.py | 55 + .../enums/types/conversion_action_category.py | 61 + .../types/conversion_action_counting_type.py | 43 + .../enums/types/conversion_action_status.py | 41 + .../v12/enums/types/conversion_action_type.py | 73 + .../enums/types/conversion_adjustment_type.py | 42 + .../conversion_attribution_event_type.py | 40 + .../conversion_custom_variable_status.py | 41 + .../types/conversion_environment_enum.py | 40 + .../v12/enums/types/conversion_lag_bucket.py | 59 + .../conversion_or_adjustment_lag_bucket.py | 83 + .../v12/enums/types/conversion_origin.py | 42 + .../types/conversion_tracking_status_enum.py | 42 + ...conversion_value_rule_primary_dimension.py | 47 + .../types/conversion_value_rule_set_status.py | 41 + .../types/conversion_value_rule_status.py | 41 + ...rion_category_channel_availability_mode.py | 46 + ...erion_category_locale_availability_mode.py | 46 + .../types/criterion_system_serving_status.py | 40 + .../v12/enums/types/criterion_type.py | 70 + .../types/custom_audience_member_type.py | 40 + .../v12/enums/types/custom_audience_status.py | 38 + .../v12/enums/types/custom_audience_type.py | 40 + .../types/custom_conversion_goal_status.py | 40 + .../types/custom_interest_member_type.py | 38 + .../v12/enums/types/custom_interest_status.py | 38 + .../v12/enums/types/custom_interest_type.py | 38 + .../enums/types/custom_placeholder_field.py | 59 + .../types/customer_match_upload_key_type.py | 41 + ...r_conversion_eligibility_failure_reason.py | 47 + .../v12/enums/types/customer_status.py | 42 + .../types/customizer_attribute_status.py | 40 + .../enums/types/customizer_attribute_type.py | 42 + .../enums/types/customizer_value_status.py | 40 + .../enums/types/data_driven_model_status.py | 40 + .../googleads/v12/enums/types/day_of_week.py | 45 + .../ads/googleads/v12/enums/types/device.py | 43 + .../enums/types/display_ad_format_setting.py | 39 + .../types/display_upload_product_type.py | 52 + .../v12/enums/types/distance_bucket.py | 67 + .../types/dsa_page_feed_criterion_field.py | 40 + .../types/education_placeholder_field.py | 56 + .../v12/enums/types/experiment_metric.py | 49 + .../types/experiment_metric_direction.py | 43 + .../v12/enums/types/experiment_status.py | 43 + .../v12/enums/types/experiment_type.py | 46 + .../enums/types/extension_setting_device.py | 38 + .../v12/enums/types/extension_type.py | 51 + .../enums/types/external_conversion_source.py | 68 + .../v12/enums/types/feed_attribute_type.py | 51 + .../feed_item_quality_approval_status.py | 42 + .../feed_item_quality_disapproval_reason.py | 58 + .../v12/enums/types/feed_item_set_status.py | 40 + .../types/feed_item_set_string_filter_type.py | 39 + .../v12/enums/types/feed_item_status.py | 40 + .../enums/types/feed_item_target_device.py | 39 + .../enums/types/feed_item_target_status.py | 40 + .../v12/enums/types/feed_item_target_type.py | 41 + .../types/feed_item_validation_status.py | 41 + .../v12/enums/types/feed_link_status.py | 40 + .../types/feed_mapping_criterion_type.py | 40 + .../v12/enums/types/feed_mapping_status.py | 40 + .../googleads/v12/enums/types/feed_origin.py | 40 + .../googleads/v12/enums/types/feed_status.py | 38 + .../enums/types/flight_placeholder_field.py | 56 + .../enums/types/frequency_cap_event_type.py | 42 + .../v12/enums/types/frequency_cap_level.py | 43 + .../enums/types/frequency_cap_time_unit.py | 41 + .../googleads/v12/enums/types/gender_type.py | 41 + .../enums/types/geo_target_constant_status.py | 38 + .../enums/types/geo_targeting_restriction.py | 39 + .../v12/enums/types/geo_targeting_type.py | 38 + .../v12/enums/types/goal_config_level.py | 41 + .../enums/types/google_ads_field_category.py | 43 + .../enums/types/google_ads_field_data_type.py | 49 + .../enums/types/google_voice_call_status.py | 40 + .../enums/types/hotel_date_selection_type.py | 40 + .../enums/types/hotel_placeholder_field.py | 59 + .../v12/enums/types/hotel_price_bucket.py | 42 + .../v12/enums/types/hotel_rate_type.py | 40 + .../types/hotel_reconciliation_status.py | 40 + .../enums/types/image_placeholder_field.py | 39 + .../v12/enums/types/income_range_type.py | 47 + .../v12/enums/types/interaction_event_type.py | 44 + .../v12/enums/types/interaction_type.py | 37 + .../googleads/v12/enums/types/invoice_type.py | 38 + .../v12/enums/types/job_placeholder_field.py | 56 + .../v12/enums/types/keyword_match_type.py | 39 + .../keyword_plan_aggregate_metric_type.py | 37 + .../types/keyword_plan_competition_level.py | 45 + .../types/keyword_plan_concept_group_type.py | 41 + .../types/keyword_plan_forecast_interval.py | 39 + .../types/keyword_plan_keyword_annotation.py | 39 + .../v12/enums/types/keyword_plan_network.py | 40 + .../googleads/v12/enums/types/label_status.py | 38 + .../types/lead_form_call_to_action_type.py | 52 + .../enums/types/lead_form_desired_intent.py | 40 + .../types/lead_form_field_user_input_type.py | 152 + ...ad_form_post_submit_call_to_action_type.py | 44 + .../types/legacy_app_install_ad_app_store.py | 43 + .../v12/enums/types/linked_account_type.py | 45 + ...ing_group_filter_bidding_category_level.py | 43 + ...ing_group_filter_custom_attribute_index.py | 43 + .../listing_group_filter_product_channel.py | 38 + .../listing_group_filter_product_condition.py | 39 + ...listing_group_filter_product_type_level.py | 41 + .../types/listing_group_filter_type_enum.py | 41 + .../types/listing_group_filter_vertical.py | 39 + .../v12/enums/types/listing_group_type.py | 38 + .../enums/types/local_placeholder_field.py | 58 + ...ion_extension_targeting_criterion_field.py | 44 + .../types/location_group_radius_units.py | 43 + .../enums/types/location_ownership_type.py | 40 + .../enums/types/location_placeholder_field.py | 44 + .../v12/enums/types/location_source_type.py | 38 + .../types/location_string_filter_type.py | 39 + .../v12/enums/types/manager_link_status.py | 43 + .../types/matching_function_context_type.py | 41 + .../enums/types/matching_function_operator.py | 41 + .../googleads/v12/enums/types/media_type.py | 42 + .../types/merchant_center_link_status.py | 42 + .../enums/types/message_placeholder_field.py | 41 + .../googleads/v12/enums/types/mime_type.py | 48 + .../v12/enums/types/minute_of_hour.py | 40 + .../v12/enums/types/mobile_app_vendor.py | 40 + .../v12/enums/types/mobile_device_type.py | 38 + .../v12/enums/types/month_of_year.py | 50 + .../enums/types/negative_geo_target_type.py | 40 + .../offline_user_data_job_failure_reason.py | 43 + .../offline_user_data_job_match_rate_range.py | 47 + .../types/offline_user_data_job_status.py | 42 + .../enums/types/offline_user_data_job_type.py | 42 + .../operating_system_version_operator_type.py | 38 + .../v12/enums/types/optimization_goal_type.py | 39 + .../v12/enums/types/parental_status_type.py | 41 + .../googleads/v12/enums/types/payment_mode.py | 40 + .../types/performance_max_upgrade_status.py | 40 + .../v12/enums/types/placeholder_type.py | 58 + .../v12/enums/types/placement_type.py | 41 + .../v12/enums/types/policy_approval_status.py | 46 + .../v12/enums/types/policy_review_status.py | 42 + .../enums/types/policy_topic_entry_type.py | 44 + ..._evidence_destination_mismatch_url_type.py | 45 + ...evidence_destination_not_working_device.py | 43 + ..._destination_not_working_dns_error_type.py | 42 + .../enums/types/positive_geo_target_type.py | 41 + .../v12/enums/types/preferred_content_type.py | 39 + .../types/price_extension_price_qualifier.py | 41 + .../enums/types/price_extension_price_unit.py | 42 + .../v12/enums/types/price_extension_type.py | 45 + .../enums/types/price_placeholder_field.py | 89 + .../types/product_bidding_category_level.py | 41 + .../types/product_bidding_category_status.py | 38 + .../v12/enums/types/product_channel.py | 38 + .../types/product_channel_exclusivity.py | 38 + .../v12/enums/types/product_condition.py | 39 + .../types/product_custom_attribute_index.py | 43 + .../v12/enums/types/product_type_level.py | 41 + .../promotion_extension_discount_modifier.py | 39 + .../types/promotion_extension_occasion.py | 76 + .../types/promotion_placeholder_field.py | 50 + .../v12/enums/types/proximity_radius_units.py | 38 + .../v12/enums/types/quality_score_bucket.py | 39 + .../v12/enums/types/reach_plan_age_range.py | 62 + .../v12/enums/types/reach_plan_network.py | 39 + .../types/real_estate_placeholder_field.py | 57 + .../v12/enums/types/recommendation_type.py | 62 + .../enums/types/resource_change_operation.py | 41 + .../v12/enums/types/resource_limit_type.py | 168 + .../v12/enums/types/response_content_type.py | 37 + .../types/search_engine_results_page_type.py | 39 + .../v12/enums/types/search_term_match_type.py | 45 + .../types/search_term_targeting_status.py | 44 + .../enums/types/seasonality_event_scope.py | 42 + .../enums/types/seasonality_event_status.py | 41 + .../enums/types/served_asset_field_type.py | 41 + .../v12/enums/types/shared_set_status.py | 38 + .../v12/enums/types/shared_set_type.py | 38 + .../types/simulation_modification_method.py | 43 + .../v12/enums/types/simulation_type.py | 46 + .../enums/types/sitelink_placeholder_field.py | 43 + .../types/sk_ad_network_ad_event_type.py | 39 + .../types/sk_ad_network_attribution_credit.py | 39 + .../enums/types/sk_ad_network_user_type.py | 39 + google/ads/googleads/v12/enums/types/slot.py | 43 + .../v12/enums/types/spending_limit_type.py | 39 + .../structured_snippet_placeholder_field.py | 38 + .../v12/enums/types/summary_row_setting.py | 39 + .../types/system_managed_entity_source.py | 39 + .../target_cpa_opt_in_recommendation_goal.py | 42 + .../types/target_impression_share_location.py | 42 + .../v12/enums/types/targeting_dimension.py | 44 + .../googleads/v12/enums/types/time_type.py | 40 + .../enums/types/tracking_code_page_format.py | 42 + .../v12/enums/types/tracking_code_type.py | 44 + .../enums/types/travel_placeholder_field.py | 59 + .../v12/enums/types/user_identifier_source.py | 43 + .../types/user_interest_taxonomy_type.py | 41 + .../enums/types/user_list_access_status.py | 38 + .../enums/types/user_list_closing_reason.py | 39 + .../types/user_list_combined_rule_operator.py | 38 + .../types/user_list_crm_data_source_type.py | 39 + .../user_list_date_rule_item_operator.py | 40 + .../types/user_list_flexible_rule_operator.py | 38 + .../types/user_list_logical_rule_operator.py | 39 + .../types/user_list_membership_status.py | 41 + .../user_list_number_rule_item_operator.py | 44 + .../types/user_list_prepopulation_status.py | 39 + .../v12/enums/types/user_list_rule_type.py | 38 + .../v12/enums/types/user_list_size_range.py | 52 + .../user_list_string_rule_item_operator.py | 46 + .../v12/enums/types/user_list_type.py | 42 + .../v12/enums/types/value_rule_device_type.py | 41 + .../value_rule_geo_location_match_type.py | 40 + .../v12/enums/types/value_rule_operation.py | 41 + .../types/value_rule_set_attachment_type.py | 40 + .../enums/types/value_rule_set_dimension.py | 42 + .../types/vanity_pharma_display_url_mode.py | 40 + .../v12/enums/types/vanity_pharma_text.py | 51 + .../v12/enums/types/video_thumbnail.py | 43 + .../enums/types/webpage_condition_operand.py | 43 + .../enums/types/webpage_condition_operator.py | 40 + google/ads/googleads/v12/errors/__init__.py | 168 + .../googleads/v12/errors/services/__init__.py | 15 + .../googleads/v12/errors/types/__init__.py | 15 + .../errors/types/access_invitation_error.py | 46 + .../types/account_budget_proposal_error.py | 63 + .../v12/errors/types/account_link_error.py | 38 + .../v12/errors/types/ad_customizer_error.py | 41 + .../googleads/v12/errors/types/ad_error.py | 188 + .../v12/errors/types/ad_group_ad_error.py | 47 + .../types/ad_group_bid_modifier_error.py | 40 + .../ad_group_criterion_customizer_error.py | 41 + .../errors/types/ad_group_criterion_error.py | 66 + .../errors/types/ad_group_customizer_error.py | 38 + .../v12/errors/types/ad_group_error.py | 50 + .../v12/errors/types/ad_group_feed_error.py | 43 + .../v12/errors/types/ad_parameter_error.py | 38 + .../v12/errors/types/ad_sharing_error.py | 39 + .../googleads/v12/errors/types/adx_error.py | 37 + .../googleads/v12/errors/types/asset_error.py | 70 + .../errors/types/asset_group_asset_error.py | 41 + .../v12/errors/types/asset_group_error.py | 46 + .../asset_group_listing_group_filter_error.py | 53 + .../v12/errors/types/asset_link_error.py | 58 + .../v12/errors/types/asset_set_asset_error.py | 42 + .../v12/errors/types/asset_set_error.py | 44 + .../v12/errors/types/asset_set_link_error.py | 41 + .../v12/errors/types/audience_error.py | 44 + .../errors/types/audience_insights_error.py | 39 + .../v12/errors/types/authentication_error.py | 54 + .../v12/errors/types/authorization_error.py | 50 + .../v12/errors/types/batch_job_error.py | 42 + .../v12/errors/types/bidding_error.py | 69 + .../errors/types/bidding_strategy_error.py | 43 + .../v12/errors/types/billing_setup_error.py | 55 + .../v12/errors/types/campaign_budget_error.py | 57 + .../types/campaign_conversion_goal_error.py | 39 + .../errors/types/campaign_criterion_error.py | 62 + .../errors/types/campaign_customizer_error.py | 38 + .../v12/errors/types/campaign_draft_error.py | 46 + .../v12/errors/types/campaign_error.py | 87 + .../errors/types/campaign_experiment_error.py | 48 + .../v12/errors/types/campaign_feed_error.py | 44 + .../errors/types/campaign_shared_set_error.py | 39 + .../v12/errors/types/change_event_error.py | 41 + .../v12/errors/types/change_status_error.py | 41 + .../v12/errors/types/collection_size_error.py | 40 + .../v12/errors/types/context_error.py | 38 + .../errors/types/conversion_action_error.py | 48 + .../conversion_adjustment_upload_error.py | 63 + .../types/conversion_custom_variable_error.py | 41 + .../conversion_goal_campaign_config_error.py | 43 + .../errors/types/conversion_upload_error.py | 85 + .../types/conversion_value_rule_error.py | 50 + .../types/conversion_value_rule_set_error.py | 51 + .../v12/errors/types/country_code_error.py | 37 + .../v12/errors/types/criterion_error.py | 172 + .../v12/errors/types/currency_code_error.py | 37 + .../v12/errors/types/custom_audience_error.py | 46 + .../types/custom_conversion_goal_error.py | 43 + .../v12/errors/types/custom_interest_error.py | 45 + .../types/customer_client_link_error.py | 46 + .../errors/types/customer_customizer_error.py | 38 + .../v12/errors/types/customer_error.py | 40 + .../v12/errors/types/customer_feed_error.py | 43 + .../types/customer_manager_link_error.py | 47 + .../types/customer_user_access_error.py | 43 + .../types/customizer_attribute_error.py | 39 + .../v12/errors/types/database_error.py | 39 + .../googleads/v12/errors/types/date_error.py | 46 + .../v12/errors/types/date_range_error.py | 41 + .../v12/errors/types/distinct_error.py | 38 + .../googleads/v12/errors/types/enum_error.py | 37 + .../ads/googleads/v12/errors/types/errors.py | 2132 ++++++++++ .../v12/errors/types/experiment_arm_error.py | 50 + .../v12/errors/types/experiment_error.py | 60 + .../errors/types/extension_feed_item_error.py | 83 + .../errors/types/extension_setting_error.py | 103 + .../types/feed_attribute_reference_error.py | 41 + .../googleads/v12/errors/types/feed_error.py | 59 + .../v12/errors/types/feed_item_error.py | 46 + .../v12/errors/types/feed_item_set_error.py | 43 + .../errors/types/feed_item_set_link_error.py | 40 + .../errors/types/feed_item_target_error.py | 46 + .../types/feed_item_validation_error.py | 143 + .../v12/errors/types/feed_mapping_error.py | 54 + .../googleads/v12/errors/types/field_error.py | 44 + .../v12/errors/types/field_mask_error.py | 40 + .../v12/errors/types/function_error.py | 52 + .../errors/types/function_parsing_error.py | 49 + .../geo_target_constant_suggestion_error.py | 44 + .../v12/errors/types/header_error.py | 38 + .../googleads/v12/errors/types/id_error.py | 37 + .../googleads/v12/errors/types/image_error.py | 75 + .../v12/errors/types/internal_error.py | 40 + .../v12/errors/types/invoice_error.py | 41 + .../types/keyword_plan_ad_group_error.py | 42 + .../keyword_plan_ad_group_keyword_error.py | 48 + .../types/keyword_plan_campaign_error.py | 46 + .../keyword_plan_campaign_keyword_error.py | 41 + .../v12/errors/types/keyword_plan_error.py | 54 + .../errors/types/keyword_plan_idea_error.py | 40 + .../googleads/v12/errors/types/label_error.py | 45 + .../v12/errors/types/language_code_error.py | 38 + .../v12/errors/types/list_operation_error.py | 38 + .../v12/errors/types/manager_link_error.py | 55 + .../v12/errors/types/media_bundle_error.py | 58 + .../v12/errors/types/media_file_error.py | 59 + .../v12/errors/types/media_upload_error.py | 72 + .../v12/errors/types/merchant_center_error.py | 40 + .../v12/errors/types/multiplier_error.py | 48 + .../v12/errors/types/mutate_error.py | 45 + .../types/new_resource_creation_error.py | 41 + .../v12/errors/types/not_allowlisted_error.py | 39 + .../v12/errors/types/not_empty_error.py | 37 + .../googleads/v12/errors/types/null_error.py | 37 + .../types/offline_user_data_job_error.py | 76 + .../types/operation_access_denied_error.py | 48 + .../v12/errors/types/operator_error.py | 37 + .../v12/errors/types/partial_failure_error.py | 39 + .../errors/types/payments_account_error.py | 39 + .../v12/errors/types/policy_finding_error.py | 38 + .../policy_validation_parameter_error.py | 43 + .../errors/types/policy_violation_error.py | 39 + .../googleads/v12/errors/types/query_error.py | 91 + .../googleads/v12/errors/types/quota_error.py | 39 + .../googleads/v12/errors/types/range_error.py | 38 + .../v12/errors/types/reach_plan_error.py | 39 + .../v12/errors/types/recommendation_error.py | 54 + .../v12/errors/types/region_code_error.py | 37 + .../v12/errors/types/request_error.py | 59 + .../types/resource_access_denied_error.py | 39 + .../resource_count_limit_exceeded_error.py | 49 + .../v12/errors/types/setting_error.py | 54 + .../errors/types/shared_criterion_error.py | 39 + .../v12/errors/types/shared_set_error.py | 40 + .../v12/errors/types/size_limit_error.py | 38 + .../v12/errors/types/smart_campaign_error.py | 43 + .../v12/errors/types/string_format_error.py | 38 + .../v12/errors/types/string_length_error.py | 39 + .../third_party_app_analytics_link_error.py | 44 + .../v12/errors/types/time_zone_error.py | 37 + .../v12/errors/types/url_field_error.py | 89 + .../v12/errors/types/user_data_error.py | 39 + .../v12/errors/types/user_list_error.py | 62 + .../types/youtube_video_registration_error.py | 41 + .../ads/googleads/v12/resources/__init__.py | 206 + .../v12/resources/services/__init__.py | 15 + .../googleads/v12/resources/types/__init__.py | 15 + .../types/accessible_bidding_strategy.py | 269 ++ .../v12/resources/types/account_budget.py | 374 ++ .../types/account_budget_proposal.py | 234 ++ .../v12/resources/types/account_link.py | 241 ++ .../ads/googleads/v12/resources/types/ad.py | 394 ++ .../googleads/v12/resources/types/ad_group.py | 297 ++ .../v12/resources/types/ad_group_ad.py | 116 + .../ad_group_ad_asset_combination_view.py | 62 + .../resources/types/ad_group_ad_asset_view.py | 136 + .../v12/resources/types/ad_group_ad_label.py | 51 + .../v12/resources/types/ad_group_asset.py | 73 + .../v12/resources/types/ad_group_asset_set.py | 60 + .../resources/types/ad_group_audience_view.py | 43 + .../resources/types/ad_group_bid_modifier.py | 166 + .../v12/resources/types/ad_group_criterion.py | 566 +++ .../types/ad_group_criterion_customizer.py | 72 + .../types/ad_group_criterion_label.py | 52 + .../types/ad_group_criterion_simulation.py | 121 + .../resources/types/ad_group_customizer.py | 68 + .../types/ad_group_extension_setting.py | 78 + .../v12/resources/types/ad_group_feed.py | 84 + .../v12/resources/types/ad_group_label.py | 51 + .../resources/types/ad_group_simulation.py | 138 + .../v12/resources/types/ad_parameter.py | 78 + .../v12/resources/types/ad_schedule_view.py | 41 + .../v12/resources/types/age_range_view.py | 40 + .../googleads/v12/resources/types/asset.py | 402 ++ .../resources/types/asset_field_type_view.py | 52 + .../v12/resources/types/asset_group.py | 94 + .../v12/resources/types/asset_group_asset.py | 87 + .../types/asset_group_listing_group_filter.py | 286 ++ .../types/asset_group_product_group_view.py | 49 + .../v12/resources/types/asset_group_signal.py | 56 + .../v12/resources/types/asset_set.py | 141 + .../v12/resources/types/asset_set_asset.py | 59 + .../resources/types/asset_set_type_view.py | 55 + .../googleads/v12/resources/types/audience.py | 78 + .../v12/resources/types/batch_job.py | 134 + .../resources/types/bidding_data_exclusion.py | 114 + .../types/bidding_seasonality_adjustment.py | 124 + .../v12/resources/types/bidding_strategy.py | 211 + .../types/bidding_strategy_simulation.py | 107 + .../v12/resources/types/billing_setup.py | 181 + .../v12/resources/types/call_view.py | 86 + .../googleads/v12/resources/types/campaign.py | 975 +++++ .../v12/resources/types/campaign_asset.py | 77 + .../v12/resources/types/campaign_asset_set.py | 60 + .../resources/types/campaign_audience_view.py | 45 + .../resources/types/campaign_bid_modifier.py | 76 + .../v12/resources/types/campaign_budget.py | 214 + .../types/campaign_conversion_goal.py | 68 + .../v12/resources/types/campaign_criterion.py | 393 ++ .../types/campaign_criterion_simulation.py | 102 + .../resources/types/campaign_customizer.py | 68 + .../v12/resources/types/campaign_draft.py | 100 + .../types/campaign_extension_setting.py | 78 + .../v12/resources/types/campaign_feed.py | 84 + .../v12/resources/types/campaign_group.py | 63 + .../v12/resources/types/campaign_label.py | 51 + .../resources/types/campaign_shared_set.py | 70 + .../resources/types/campaign_simulation.py | 148 + .../v12/resources/types/carrier_constant.py | 58 + .../v12/resources/types/change_event.py | 284 ++ .../v12/resources/types/change_status.py | 151 + .../v12/resources/types/click_view.py | 103 + .../v12/resources/types/combined_audience.py | 64 + .../v12/resources/types/conversion_action.py | 317 ++ .../types/conversion_custom_variable.py | 83 + .../types/conversion_goal_campaign_config.py | 61 + .../resources/types/conversion_value_rule.py | 162 + .../types/conversion_value_rule_set.py | 106 + .../v12/resources/types/currency_constant.py | 65 + .../v12/resources/types/custom_audience.py | 136 + .../resources/types/custom_conversion_goal.py | 61 + .../v12/resources/types/custom_interest.py | 112 + .../googleads/v12/resources/types/customer.py | 282 ++ .../v12/resources/types/customer_asset.py | 69 + .../v12/resources/types/customer_asset_set.py | 60 + .../v12/resources/types/customer_client.py | 117 + .../resources/types/customer_client_link.py | 68 + .../types/customer_conversion_goal.py | 68 + .../resources/types/customer_customizer.py | 64 + .../types/customer_extension_setting.py | 69 + .../v12/resources/types/customer_feed.py | 78 + .../v12/resources/types/customer_label.py | 58 + .../resources/types/customer_manager_link.py | 61 + .../types/customer_negative_criterion.py | 123 + .../resources/types/customer_user_access.py | 76 + .../types/customer_user_access_invitation.py | 71 + .../resources/types/customizer_attribute.py | 74 + .../resources/types/detail_placement_view.py | 84 + .../resources/types/detailed_demographic.py | 69 + .../resources/types/display_keyword_view.py | 40 + .../v12/resources/types/distance_view.py | 62 + .../v12/resources/types/domain_category.py | 105 + .../dynamic_search_ads_search_term_view.py | 89 + .../types/expanded_landing_page_view.py | 48 + .../v12/resources/types/experiment.py | 135 + .../v12/resources/types/experiment_arm.py | 70 + .../resources/types/extension_feed_item.py | 263 ++ .../ads/googleads/v12/resources/types/feed.py | 279 ++ .../v12/resources/types/feed_item.py | 326 ++ .../v12/resources/types/feed_item_set.py | 98 + .../v12/resources/types/feed_item_set_link.py | 45 + .../v12/resources/types/feed_item_target.py | 124 + .../v12/resources/types/feed_mapping.py | 384 ++ .../resources/types/feed_placeholder_view.py | 52 + .../v12/resources/types/gender_view.py | 40 + .../resources/types/geo_target_constant.py | 87 + .../v12/resources/types/geographic_view.py | 60 + .../v12/resources/types/google_ads_field.py | 129 + .../resources/types/group_placement_view.py | 73 + .../v12/resources/types/hotel_group_view.py | 40 + .../resources/types/hotel_performance_view.py | 40 + .../resources/types/hotel_reconciliation.py | 117 + .../v12/resources/types/income_range_view.py | 40 + .../googleads/v12/resources/types/invoice.py | 473 +++ .../v12/resources/types/keyword_plan.py | 101 + .../resources/types/keyword_plan_ad_group.py | 68 + .../types/keyword_plan_ad_group_keyword.py | 83 + .../resources/types/keyword_plan_campaign.py | 105 + .../types/keyword_plan_campaign_keyword.py | 75 + .../resources/types/keyword_theme_constant.py | 63 + .../v12/resources/types/keyword_view.py | 40 + .../googleads/v12/resources/types/label.py | 66 + .../v12/resources/types/landing_page_view.py | 47 + .../v12/resources/types/language_constant.py | 64 + .../types/lead_form_submission_data.py | 122 + .../v12/resources/types/life_event.py | 68 + .../v12/resources/types/location_view.py | 41 + .../resources/types/managed_placement_view.py | 40 + .../v12/resources/types/media_file.py | 220 + .../resources/types/merchant_center_link.py | 64 + .../types/mobile_app_category_constant.py | 52 + .../resources/types/mobile_device_constant.py | 73 + .../resources/types/offline_user_data_job.py | 141 + .../operating_system_version_constant.py | 77 + .../types/paid_organic_search_term_view.py | 47 + .../resources/types/parental_status_view.py | 40 + .../v12/resources/types/payments_account.py | 85 + .../v12/resources/types/per_store_view.py | 46 + .../product_bidding_category_constant.py | 95 + .../v12/resources/types/product_group_view.py | 40 + .../v12/resources/types/recommendation.py | 941 +++++ .../v12/resources/types/remarketing_action.py | 63 + .../v12/resources/types/search_term_view.py | 63 + .../v12/resources/types/shared_criterion.py | 129 + .../v12/resources/types/shared_set.py | 88 + .../types/shopping_performance_view.py | 45 + .../types/smart_campaign_search_term_view.py | 48 + .../resources/types/smart_campaign_setting.py | 133 + .../types/third_party_app_analytics_link.py | 51 + .../v12/resources/types/topic_constant.py | 62 + .../v12/resources/types/topic_view.py | 40 + .../v12/resources/types/user_interest.py | 83 + .../v12/resources/types/user_list.py | 270 ++ .../v12/resources/types/user_location_view.py | 56 + .../googleads/v12/resources/types/video.py | 62 + .../v12/resources/types/webpage_view.py | 40 + google/ads/googleads/v12/services/__init__.py | 15 + .../v12/services/services/__init__.py | 15 + .../__init__.py | 18 + .../account_budget_proposal_service/client.py | 543 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 290 ++ .../services/account_link_service/__init__.py | 18 + .../services/account_link_service/client.py | 600 +++ .../transports/__init__.py | 31 + .../account_link_service/transports/base.py | 171 + .../account_link_service/transports/grpc.py | 311 ++ .../ad_group_ad_label_service/__init__.py | 18 + .../ad_group_ad_label_service/client.py | 529 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 277 ++ .../services/ad_group_ad_service/__init__.py | 18 + .../services/ad_group_ad_service/client.py | 553 +++ .../transports/__init__.py | 31 + .../ad_group_ad_service/transports/base.py | 154 + .../ad_group_ad_service/transports/grpc.py | 289 ++ .../ad_group_asset_service/__init__.py | 18 + .../services/ad_group_asset_service/client.py | 526 +++ .../transports/__init__.py | 31 + .../ad_group_asset_service/transports/base.py | 154 + .../ad_group_asset_service/transports/grpc.py | 277 ++ .../ad_group_asset_set_service/__init__.py | 18 + .../ad_group_asset_set_service/client.py | 526 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 271 ++ .../ad_group_bid_modifier_service/__init__.py | 18 + .../ad_group_bid_modifier_service/client.py | 525 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 286 ++ .../__init__.py | 18 + .../client.py | 545 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 281 ++ .../__init__.py | 18 + .../client.py | 542 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 281 ++ .../ad_group_criterion_service/__init__.py | 18 + .../ad_group_criterion_service/client.py | 547 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 287 ++ .../ad_group_customizer_service/__init__.py | 18 + .../ad_group_customizer_service/client.py | 531 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 271 ++ .../__init__.py | 18 + .../client.py | 548 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 292 ++ .../ad_group_feed_service/__init__.py | 18 + .../services/ad_group_feed_service/client.py | 524 +++ .../transports/__init__.py | 31 + .../ad_group_feed_service/transports/base.py | 154 + .../ad_group_feed_service/transports/grpc.py | 281 ++ .../ad_group_label_service/__init__.py | 18 + .../services/ad_group_label_service/client.py | 522 +++ .../transports/__init__.py | 31 + .../ad_group_label_service/transports/base.py | 154 + .../ad_group_label_service/transports/grpc.py | 277 ++ .../services/ad_group_service/__init__.py | 18 + .../services/ad_group_service/client.py | 524 +++ .../ad_group_service/transports/__init__.py | 31 + .../ad_group_service/transports/base.py | 154 + .../ad_group_service/transports/grpc.py | 284 ++ .../services/ad_parameter_service/__init__.py | 18 + .../services/ad_parameter_service/client.py | 515 +++ .../transports/__init__.py | 31 + .../ad_parameter_service/transports/base.py | 154 + .../ad_parameter_service/transports/grpc.py | 275 ++ .../services/services/ad_service/__init__.py | 18 + .../services/services/ad_service/client.py | 568 +++ .../ad_service/transports/__init__.py | 29 + .../services/ad_service/transports/base.py | 162 + .../services/ad_service/transports/grpc.py | 313 ++ .../asset_group_asset_service/__init__.py | 18 + .../asset_group_asset_service/client.py | 526 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 271 ++ .../__init__.py | 18 + .../client.py | 523 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 281 ++ .../services/asset_group_service/__init__.py | 18 + .../services/asset_group_service/client.py | 497 +++ .../transports/__init__.py | 31 + .../asset_group_service/transports/base.py | 154 + .../asset_group_service/transports/grpc.py | 269 ++ .../asset_group_signal_service/__init__.py | 18 + .../asset_group_signal_service/client.py | 512 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 271 ++ .../services/asset_service/__init__.py | 18 + .../services/services/asset_service/client.py | 505 +++ .../asset_service/transports/__init__.py | 31 + .../services/asset_service/transports/base.py | 154 + .../services/asset_service/transports/grpc.py | 282 ++ .../asset_set_asset_service/__init__.py | 18 + .../asset_set_asset_service/client.py | 521 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 271 ++ .../services/asset_set_service/__init__.py | 18 + .../services/asset_set_service/client.py | 477 +++ .../asset_set_service/transports/__init__.py | 31 + .../asset_set_service/transports/base.py | 154 + .../asset_set_service/transports/grpc.py | 269 ++ .../audience_insights_service/__init__.py | 18 + .../audience_insights_service/client.py | 781 ++++ .../transports/__init__.py | 31 + .../transports/base.py | 213 + .../transports/grpc.py | 392 ++ .../services/audience_service/__init__.py | 18 + .../services/audience_service/client.py | 476 +++ .../audience_service/transports/__init__.py | 31 + .../audience_service/transports/base.py | 154 + .../audience_service/transports/grpc.py | 270 ++ .../services/batch_job_service/__init__.py | 18 + .../services/batch_job_service/client.py | 2257 ++++++++++ .../services/batch_job_service/pagers.py | 81 + .../batch_job_service/transports/__init__.py | 31 + .../batch_job_service/transports/base.py | 208 + .../batch_job_service/transports/grpc.py | 403 ++ .../__init__.py | 18 + .../bidding_data_exclusion_service/client.py | 514 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 275 ++ .../__init__.py | 18 + .../client.py | 518 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 281 ++ .../bidding_strategy_service/__init__.py | 18 + .../bidding_strategy_service/client.py | 505 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 284 ++ .../billing_setup_service/__init__.py | 18 + .../services/billing_setup_service/client.py | 511 +++ .../transports/__init__.py | 31 + .../billing_setup_service/transports/base.py | 154 + .../billing_setup_service/transports/grpc.py | 283 ++ .../campaign_asset_service/__init__.py | 18 + .../services/campaign_asset_service/client.py | 528 +++ .../transports/__init__.py | 31 + .../campaign_asset_service/transports/base.py | 154 + .../campaign_asset_service/transports/grpc.py | 277 ++ .../campaign_asset_set_service/__init__.py | 18 + .../campaign_asset_set_service/client.py | 528 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 271 ++ .../campaign_bid_modifier_service/__init__.py | 18 + .../campaign_bid_modifier_service/client.py | 526 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 285 ++ .../campaign_budget_service/__init__.py | 18 + .../campaign_budget_service/client.py | 495 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 280 ++ .../__init__.py | 18 + .../client.py | 518 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 276 ++ .../campaign_criterion_service/__init__.py | 18 + .../campaign_criterion_service/client.py | 524 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 285 ++ .../campaign_customizer_service/__init__.py | 18 + .../campaign_customizer_service/client.py | 532 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 273 ++ .../campaign_draft_service/__init__.py | 18 + .../services/campaign_draft_service/client.py | 732 ++++ .../services/campaign_draft_service/pagers.py | 88 + .../transports/__init__.py | 31 + .../campaign_draft_service/transports/base.py | 193 + .../campaign_draft_service/transports/grpc.py | 379 ++ .../__init__.py | 18 + .../client.py | 547 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 291 ++ .../campaign_feed_service/__init__.py | 18 + .../services/campaign_feed_service/client.py | 527 +++ .../transports/__init__.py | 31 + .../campaign_feed_service/transports/base.py | 154 + .../campaign_feed_service/transports/grpc.py | 282 ++ .../campaign_group_service/__init__.py | 18 + .../services/campaign_group_service/client.py | 486 +++ .../transports/__init__.py | 31 + .../campaign_group_service/transports/base.py | 154 + .../campaign_group_service/transports/grpc.py | 271 ++ .../campaign_label_service/__init__.py | 18 + .../services/campaign_label_service/client.py | 525 +++ .../transports/__init__.py | 31 + .../campaign_label_service/transports/base.py | 154 + .../campaign_label_service/transports/grpc.py | 277 ++ .../services/campaign_service/__init__.py | 18 + .../services/campaign_service/client.py | 609 +++ .../campaign_service/transports/__init__.py | 31 + .../campaign_service/transports/base.py | 154 + .../campaign_service/transports/grpc.py | 286 ++ .../campaign_shared_set_service/__init__.py | 18 + .../campaign_shared_set_service/client.py | 538 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 281 ++ .../conversion_action_service/__init__.py | 18 + .../conversion_action_service/client.py | 513 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 279 ++ .../__init__.py | 18 + .../client.py | 505 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 284 ++ .../__init__.py | 18 + .../client.py | 517 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 283 ++ .../__init__.py | 18 + .../client.py | 533 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 281 ++ .../conversion_upload_service/__init__.py | 18 + .../conversion_upload_service/client.py | 631 +++ .../transports/__init__.py | 31 + .../transports/base.py | 171 + .../transports/grpc.py | 311 ++ .../conversion_value_rule_service/__init__.py | 18 + .../conversion_value_rule_service/client.py | 555 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 275 ++ .../__init__.py | 18 + .../client.py | 547 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 278 ++ .../custom_audience_service/__init__.py | 18 + .../custom_audience_service/client.py | 493 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 279 ++ .../__init__.py | 18 + .../custom_conversion_goal_service/client.py | 515 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 275 ++ .../custom_interest_service/__init__.py | 18 + .../custom_interest_service/client.py | 492 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 278 ++ .../customer_asset_service/__init__.py | 18 + .../services/customer_asset_service/client.py | 508 +++ .../transports/__init__.py | 31 + .../customer_asset_service/transports/base.py | 154 + .../customer_asset_service/transports/grpc.py | 276 ++ .../customer_asset_set_service/__init__.py | 18 + .../customer_asset_set_service/client.py | 519 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 271 ++ .../customer_client_link_service/__init__.py | 18 + .../customer_client_link_service/client.py | 510 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 280 ++ .../__init__.py | 18 + .../client.py | 499 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 276 ++ .../customer_customizer_service/__init__.py | 18 + .../customer_customizer_service/client.py | 515 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 273 ++ .../__init__.py | 18 + .../client.py | 528 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 290 ++ .../customer_feed_service/__init__.py | 18 + .../services/customer_feed_service/client.py | 509 +++ .../transports/__init__.py | 31 + .../customer_feed_service/transports/base.py | 154 + .../customer_feed_service/transports/grpc.py | 282 ++ .../customer_label_service/__init__.py | 18 + .../services/customer_label_service/client.py | 517 +++ .../transports/__init__.py | 31 + .../customer_label_service/transports/base.py | 154 + .../customer_label_service/transports/grpc.py | 276 ++ .../customer_manager_link_service/__init__.py | 18 + .../customer_manager_link_service/client.py | 633 +++ .../transports/__init__.py | 31 + .../transports/base.py | 175 + .../transports/grpc.py | 319 ++ .../__init__.py | 18 + .../client.py | 503 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 283 ++ .../services/customer_service/__init__.py | 18 + .../services/customer_service/client.py | 646 +++ .../customer_service/transports/__init__.py | 31 + .../customer_service/transports/base.py | 188 + .../customer_service/transports/grpc.py | 347 ++ .../__init__.py | 18 + .../client.py | 504 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 286 ++ .../customer_user_access_service/__init__.py | 18 + .../customer_user_access_service/client.py | 495 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 279 ++ .../customizer_attribute_service/__init__.py | 18 + .../customizer_attribute_service/client.py | 496 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 273 ++ .../experiment_arm_service/__init__.py | 18 + .../services/experiment_arm_service/client.py | 526 +++ .../transports/__init__.py | 31 + .../experiment_arm_service/transports/base.py | 154 + .../experiment_arm_service/transports/grpc.py | 276 ++ .../services/experiment_service/__init__.py | 18 + .../services/experiment_service/client.py | 1005 +++++ .../services/experiment_service/pagers.py | 88 + .../experiment_service/transports/__init__.py | 31 + .../experiment_service/transports/base.py | 234 ++ .../experiment_service/transports/grpc.py | 480 +++ .../extension_feed_item_service/__init__.py | 18 + .../extension_feed_item_service/client.py | 563 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 282 ++ .../services/feed_item_service/__init__.py | 18 + .../services/feed_item_service/client.py | 506 +++ .../feed_item_service/transports/__init__.py | 31 + .../feed_item_service/transports/base.py | 154 + .../feed_item_service/transports/grpc.py | 281 ++ .../feed_item_set_link_service/__init__.py | 18 + .../feed_item_set_link_service/client.py | 539 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 274 ++ .../feed_item_set_service/__init__.py | 18 + .../services/feed_item_set_service/client.py | 505 +++ .../transports/__init__.py | 31 + .../feed_item_set_service/transports/base.py | 154 + .../feed_item_set_service/transports/grpc.py | 276 ++ .../feed_item_target_service/__init__.py | 18 + .../feed_item_target_service/client.py | 568 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 280 ++ .../services/feed_mapping_service/__init__.py | 18 + .../services/feed_mapping_service/client.py | 510 +++ .../transports/__init__.py | 31 + .../feed_mapping_service/transports/base.py | 154 + .../feed_mapping_service/transports/grpc.py | 279 ++ .../services/feed_service/__init__.py | 18 + .../services/services/feed_service/client.py | 483 +++ .../feed_service/transports/__init__.py | 31 + .../services/feed_service/transports/base.py | 154 + .../services/feed_service/transports/grpc.py | 279 ++ .../geo_target_constant_service/__init__.py | 18 + .../geo_target_constant_service/client.py | 451 ++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 276 ++ .../google_ads_field_service/__init__.py | 18 + .../google_ads_field_service/client.py | 561 +++ .../google_ads_field_service/pagers.py | 88 + .../transports/__init__.py | 31 + .../transports/base.py | 172 + .../transports/grpc.py | 309 ++ .../services/google_ads_service/__init__.py | 18 + .../services/google_ads_service/client.py | 3662 +++++++++++++++++ .../services/google_ads_service/pagers.py | 81 + .../google_ads_service/transports/__init__.py | 31 + .../google_ads_service/transports/base.py | 184 + .../google_ads_service/transports/grpc.py | 424 ++ .../services/invoice_service/__init__.py | 18 + .../services/invoice_service/client.py | 509 +++ .../invoice_service/transports/__init__.py | 31 + .../invoice_service/transports/base.py | 154 + .../invoice_service/transports/grpc.py | 275 ++ .../__init__.py | 18 + .../client.py | 534 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 291 ++ .../keyword_plan_ad_group_service/__init__.py | 18 + .../keyword_plan_ad_group_service/client.py | 525 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 283 ++ .../__init__.py | 18 + .../client.py | 532 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 292 ++ .../keyword_plan_campaign_service/__init__.py | 18 + .../keyword_plan_campaign_service/client.py | 549 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 283 ++ .../keyword_plan_idea_service/__init__.py | 18 + .../keyword_plan_idea_service/client.py | 592 +++ .../keyword_plan_idea_service/pagers.py | 89 + .../transports/__init__.py | 31 + .../transports/base.py | 190 + .../transports/grpc.py | 350 ++ .../services/keyword_plan_service/__init__.py | 18 + .../services/keyword_plan_service/client.py | 850 ++++ .../transports/__init__.py | 31 + .../keyword_plan_service/transports/base.py | 222 + .../keyword_plan_service/transports/grpc.py | 431 ++ .../__init__.py | 18 + .../keyword_theme_constant_service/client.py | 460 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 279 ++ .../services/label_service/__init__.py | 18 + .../services/services/label_service/client.py | 483 +++ .../label_service/transports/__init__.py | 31 + .../services/label_service/transports/base.py | 154 + .../services/label_service/transports/grpc.py | 279 ++ .../services/media_file_service/__init__.py | 18 + .../services/media_file_service/client.py | 486 +++ .../media_file_service/transports/__init__.py | 31 + .../media_file_service/transports/base.py | 154 + .../media_file_service/transports/grpc.py | 278 ++ .../merchant_center_link_service/__init__.py | 18 + .../merchant_center_link_service/client.py | 673 +++ .../transports/__init__.py | 31 + .../transports/base.py | 193 + .../transports/grpc.py | 349 ++ .../offline_user_data_job_service/__init__.py | 18 + .../offline_user_data_job_service/client.py | 717 ++++ .../transports/__init__.py | 31 + .../transports/base.py | 197 + .../transports/grpc.py | 377 ++ .../payments_account_service/__init__.py | 18 + .../payments_account_service/client.py | 497 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 278 ++ .../services/reach_plan_service/__init__.py | 18 + .../services/reach_plan_service/client.py | 617 +++ .../reach_plan_service/transports/__init__.py | 31 + .../reach_plan_service/transports/base.py | 188 + .../reach_plan_service/transports/grpc.py | 352 ++ .../recommendation_service/__init__.py | 18 + .../services/recommendation_service/client.py | 608 +++ .../transports/__init__.py | 31 + .../recommendation_service/transports/base.py | 171 + .../recommendation_service/transports/grpc.py | 311 ++ .../remarketing_action_service/__init__.py | 18 + .../remarketing_action_service/client.py | 500 +++ .../transports/__init__.py | 31 + .../transports/base.py | 156 + .../transports/grpc.py | 276 ++ .../shared_criterion_service/__init__.py | 18 + .../shared_criterion_service/client.py | 519 +++ .../transports/__init__.py | 31 + .../transports/base.py | 154 + .../transports/grpc.py | 281 ++ .../services/shared_set_service/__init__.py | 18 + .../services/shared_set_service/client.py | 488 +++ .../shared_set_service/transports/__init__.py | 31 + .../shared_set_service/transports/base.py | 154 + .../shared_set_service/transports/grpc.py | 280 ++ .../__init__.py | 18 + .../smart_campaign_setting_service/client.py | 511 +++ .../transports/__init__.py | 31 + .../transports/base.py | 158 + .../transports/grpc.py | 274 ++ .../__init__.py | 18 + .../smart_campaign_suggest_service/client.py | 610 +++ .../transports/__init__.py | 31 + .../transports/base.py | 198 + .../transports/grpc.py | 341 ++ .../__init__.py | 18 + .../client.py | 471 +++ .../transports/__init__.py | 31 + .../transports/base.py | 160 + .../transports/grpc.py | 286 ++ .../services/user_data_service/__init__.py | 18 + .../services/user_data_service/client.py | 442 ++ .../user_data_service/transports/__init__.py | 31 + .../user_data_service/transports/base.py | 154 + .../user_data_service/transports/grpc.py | 281 ++ .../services/user_list_service/__init__.py | 18 + .../services/user_list_service/client.py | 486 +++ .../user_list_service/transports/__init__.py | 31 + .../user_list_service/transports/base.py | 154 + .../user_list_service/transports/grpc.py | 278 ++ .../googleads/v12/services/types/__init__.py | 15 + .../types/account_budget_proposal_service.py | 132 + .../services/types/account_link_service.py | 173 + .../types/ad_group_ad_label_service.py | 131 + .../v12/services/types/ad_group_ad_service.py | 178 + .../services/types/ad_group_asset_service.py | 171 + .../types/ad_group_asset_set_service.py | 153 + .../types/ad_group_bid_modifier_service.py | 173 + .../ad_group_criterion_customizer_service.py | 158 + .../types/ad_group_criterion_label_service.py | 132 + .../types/ad_group_criterion_service.py | 187 + .../types/ad_group_customizer_service.py | 154 + .../ad_group_extension_setting_service.py | 174 + .../services/types/ad_group_feed_service.py | 171 + .../services/types/ad_group_label_service.py | 131 + .../v12/services/types/ad_group_service.py | 168 + .../services/types/ad_parameter_service.py | 171 + .../v12/services/types/ad_service.py | 162 + .../types/asset_group_asset_service.py | 148 + ...sset_group_listing_group_filter_service.py | 167 + .../v12/services/types/asset_group_service.py | 141 + .../types/asset_group_signal_service.py | 153 + .../v12/services/types/asset_service.py | 157 + .../services/types/asset_set_asset_service.py | 151 + .../v12/services/types/asset_set_service.py | 167 + .../types/audience_insights_service.py | 782 ++++ .../v12/services/types/audience_service.py | 160 + .../v12/services/types/batch_job_service.py | 268 ++ .../types/bidding_data_exclusion_service.py | 173 + .../bidding_seasonality_adjustment_service.py | 177 + .../types/bidding_strategy_service.py | 171 + .../services/types/billing_setup_service.py | 110 + .../services/types/campaign_asset_service.py | 171 + .../types/campaign_asset_set_service.py | 153 + .../types/campaign_bid_modifier_service.py | 173 + .../services/types/campaign_budget_service.py | 171 + .../types/campaign_conversion_goal_service.py | 108 + .../types/campaign_criterion_service.py | 173 + .../types/campaign_customizer_service.py | 154 + .../services/types/campaign_draft_service.py | 242 ++ .../campaign_extension_setting_service.py | 174 + .../services/types/campaign_feed_service.py | 171 + .../services/types/campaign_group_service.py | 171 + .../services/types/campaign_label_service.py | 133 + .../v12/services/types/campaign_service.py | 168 + .../types/campaign_shared_set_service.py | 155 + .../types/conversion_action_service.py | 174 + .../conversion_adjustment_upload_service.py | 279 ++ .../conversion_custom_variable_service.py | 167 + ...conversion_goal_campaign_config_service.py | 139 + .../types/conversion_upload_service.py | 525 +++ .../types/conversion_value_rule_service.py | 174 + .../conversion_value_rule_set_service.py | 174 + .../services/types/custom_audience_service.py | 132 + .../types/custom_conversion_goal_service.py | 156 + .../services/types/custom_interest_service.py | 124 + .../services/types/customer_asset_service.py | 171 + .../types/customer_asset_set_service.py | 153 + .../types/customer_client_link_service.py | 125 + .../types/customer_conversion_goal_service.py | 108 + .../types/customer_customizer_service.py | 154 + .../customer_extension_setting_service.py | 174 + .../services/types/customer_feed_service.py | 171 + .../services/types/customer_label_service.py | 133 + .../types/customer_manager_link_service.py | 158 + .../customer_negative_criterion_service.py | 155 + .../v12/services/types/customer_service.py | 200 + ...customer_user_access_invitation_service.py | 117 + .../types/customer_user_access_service.py | 117 + .../types/customizer_attribute_service.py | 161 + .../services/types/experiment_arm_service.py | 169 + .../v12/services/types/experiment_service.py | 324 ++ .../types/extension_feed_item_service.py | 173 + .../v12/services/types/feed_item_service.py | 168 + .../types/feed_item_set_link_service.py | 132 + .../services/types/feed_item_set_service.py | 148 + .../types/feed_item_target_service.py | 152 + .../services/types/feed_mapping_service.py | 152 + .../v12/services/types/feed_service.py | 160 + .../types/geo_target_constant_service.py | 161 + .../types/google_ads_field_service.py | 97 + .../v12/services/types/google_ads_service.py | 3420 +++++++++++++++ .../v12/services/types/invoice_service.py | 74 + .../keyword_plan_ad_group_keyword_service.py | 157 + .../types/keyword_plan_ad_group_service.py | 152 + .../keyword_plan_campaign_keyword_service.py | 155 + .../types/keyword_plan_campaign_service.py | 150 + .../types/keyword_plan_idea_service.py | 508 +++ .../services/types/keyword_plan_service.py | 541 +++ .../types/keyword_theme_constant_service.py | 71 + .../v12/services/types/label_service.py | 160 + .../v12/services/types/media_file_service.py | 140 + .../types/merchant_center_link_service.py | 168 + .../types/offline_user_data_job_service.py | 201 + .../types/payments_account_service.py | 55 + .../v12/services/types/reach_plan_service.py | 880 ++++ .../services/types/recommendation_service.py | 612 +++ .../types/remarketing_action_service.py | 141 + .../types/shared_criterion_service.py | 152 + .../v12/services/types/shared_set_service.py | 170 + .../types/smart_campaign_setting_service.py | 144 + .../types/smart_campaign_suggest_service.py | 353 ++ .../third_party_app_analytics_link_service.py | 49 + .../v12/services/types/user_data_service.py | 128 + .../v12/services/types/user_list_service.py | 143 + google/ads/googleads/v12/types/__init__.py | 15 + noxfile.py | 6 +- setup.py | 12 +- tests/fixtures/protobuf_fixture_pb2.py | 17 +- .../interceptors/metadata_interceptor_test.py | 5 +- 1449 files changed, 194598 insertions(+), 4141 deletions(-) delete mode 100755 examples/advanced_operations/add_dynamic_page_feed_asset.py delete mode 100755 examples/advanced_operations/add_local_campaign.py delete mode 100755 examples/advanced_operations/add_smart_display_ad.py rename examples/error_handling/{handle_expanded_text_ad_policy_violations.py => handle_responsive_search_ad_policy_violations.py} (72%) delete mode 100644 examples/migration/campaign_management/README.md delete mode 100755 examples/migration/campaign_management/create_complete_campaign_adwords_api_only.py delete mode 100755 examples/migration/campaign_management/create_complete_campaign_both_apis_phase_1.py delete mode 100755 examples/migration/campaign_management/create_complete_campaign_both_apis_phase_2.py delete mode 100755 examples/migration/campaign_management/create_complete_campaign_both_apis_phase_3.py delete mode 100755 examples/migration/campaign_management/create_complete_campaign_both_apis_phase_4.py delete mode 100755 examples/migration/campaign_management/create_complete_campaign_googleads_api_only.py delete mode 100644 examples/migration/campaign_management/requirements.txt rename examples/{migration => misc}/campaign_report_to_csv.py (76%) mode change 100644 => 100755 delete mode 100644 examples/shopping_ads/add_shopping_smart_ad.py create mode 100644 google/ads/googleads/v12/__init__.py create mode 100644 google/ads/googleads/v12/common/__init__.py create mode 100644 google/ads/googleads/v12/common/services/__init__.py create mode 100644 google/ads/googleads/v12/common/types/__init__.py create mode 100644 google/ads/googleads/v12/common/types/ad_asset.py create mode 100644 google/ads/googleads/v12/common/types/ad_type_infos.py create mode 100644 google/ads/googleads/v12/common/types/asset_policy.py create mode 100644 google/ads/googleads/v12/common/types/asset_set_types.py create mode 100644 google/ads/googleads/v12/common/types/asset_types.py create mode 100644 google/ads/googleads/v12/common/types/asset_usage.py create mode 100644 google/ads/googleads/v12/common/types/audiences.py create mode 100644 google/ads/googleads/v12/common/types/bidding.py create mode 100644 google/ads/googleads/v12/common/types/click_location.py create mode 100644 google/ads/googleads/v12/common/types/criteria.py create mode 100644 google/ads/googleads/v12/common/types/criterion_category_availability.py create mode 100644 google/ads/googleads/v12/common/types/custom_parameter.py create mode 100644 google/ads/googleads/v12/common/types/customizer_value.py create mode 100644 google/ads/googleads/v12/common/types/dates.py create mode 100644 google/ads/googleads/v12/common/types/explorer_auto_optimizer_setting.py create mode 100644 google/ads/googleads/v12/common/types/extensions.py create mode 100644 google/ads/googleads/v12/common/types/feed_common.py create mode 100644 google/ads/googleads/v12/common/types/feed_item_set_filter_type_infos.py create mode 100644 google/ads/googleads/v12/common/types/final_app_url.py create mode 100644 google/ads/googleads/v12/common/types/frequency_cap.py create mode 100644 google/ads/googleads/v12/common/types/keyword_plan_common.py create mode 100644 google/ads/googleads/v12/common/types/matching_function.py create mode 100644 google/ads/googleads/v12/common/types/metric_goal.py create mode 100644 google/ads/googleads/v12/common/types/metrics.py create mode 100644 google/ads/googleads/v12/common/types/offline_user_data.py create mode 100644 google/ads/googleads/v12/common/types/policy.py create mode 100644 google/ads/googleads/v12/common/types/policy_summary.py create mode 100644 google/ads/googleads/v12/common/types/real_time_bidding_setting.py create mode 100644 google/ads/googleads/v12/common/types/segments.py create mode 100644 google/ads/googleads/v12/common/types/simulation.py create mode 100644 google/ads/googleads/v12/common/types/tag_snippet.py create mode 100644 google/ads/googleads/v12/common/types/targeting_setting.py create mode 100644 google/ads/googleads/v12/common/types/text_label.py create mode 100644 google/ads/googleads/v12/common/types/url_collection.py create mode 100644 google/ads/googleads/v12/common/types/user_lists.py create mode 100644 google/ads/googleads/v12/common/types/value.py create mode 100644 google/ads/googleads/v12/enums/__init__.py create mode 100644 google/ads/googleads/v12/enums/services/__init__.py create mode 100644 google/ads/googleads/v12/enums/types/__init__.py create mode 100644 google/ads/googleads/v12/enums/types/access_invitation_status.py create mode 100644 google/ads/googleads/v12/enums/types/access_reason.py create mode 100644 google/ads/googleads/v12/enums/types/access_role.py create mode 100644 google/ads/googleads/v12/enums/types/account_budget_proposal_status.py create mode 100644 google/ads/googleads/v12/enums/types/account_budget_proposal_type.py create mode 100644 google/ads/googleads/v12/enums/types/account_budget_status.py create mode 100644 google/ads/googleads/v12/enums/types/account_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_customizer_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/ad_destination_type.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_ad_rotation_mode.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_ad_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_criterion_approval_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_criterion_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_group_type.py create mode 100644 google/ads/googleads/v12/enums/types/ad_network_type.py create mode 100644 google/ads/googleads/v12/enums/types/ad_serving_optimization_status.py create mode 100644 google/ads/googleads/v12/enums/types/ad_strength.py create mode 100644 google/ads/googleads/v12/enums/types/ad_type.py create mode 100644 google/ads/googleads/v12/enums/types/advertising_channel_sub_type.py create mode 100644 google/ads/googleads/v12/enums/types/advertising_channel_type.py create mode 100644 google/ads/googleads/v12/enums/types/affiliate_location_feed_relationship_type.py create mode 100644 google/ads/googleads/v12/enums/types/affiliate_location_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/age_range_type.py create mode 100644 google/ads/googleads/v12/enums/types/app_campaign_app_store.py create mode 100644 google/ads/googleads/v12/enums/types/app_campaign_bidding_strategy_goal_type.py create mode 100644 google/ads/googleads/v12/enums/types/app_payment_model_type.py create mode 100644 google/ads/googleads/v12/enums/types/app_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/app_store.py create mode 100644 google/ads/googleads/v12/enums/types/app_url_operating_system_type.py create mode 100644 google/ads/googleads/v12/enums/types/asset_field_type.py create mode 100644 google/ads/googleads/v12/enums/types/asset_group_status.py create mode 100644 google/ads/googleads/v12/enums/types/asset_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/asset_performance_label.py create mode 100644 google/ads/googleads/v12/enums/types/asset_set_asset_status.py create mode 100644 google/ads/googleads/v12/enums/types/asset_set_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/asset_set_status.py create mode 100644 google/ads/googleads/v12/enums/types/asset_set_type.py create mode 100644 google/ads/googleads/v12/enums/types/asset_source.py create mode 100644 google/ads/googleads/v12/enums/types/asset_type.py create mode 100644 google/ads/googleads/v12/enums/types/async_action_status.py create mode 100644 google/ads/googleads/v12/enums/types/attribution_model.py create mode 100644 google/ads/googleads/v12/enums/types/audience_insights_dimension.py create mode 100644 google/ads/googleads/v12/enums/types/audience_status.py create mode 100644 google/ads/googleads/v12/enums/types/batch_job_status.py create mode 100644 google/ads/googleads/v12/enums/types/bid_modifier_source.py create mode 100644 google/ads/googleads/v12/enums/types/bidding_source.py create mode 100644 google/ads/googleads/v12/enums/types/bidding_strategy_status.py create mode 100644 google/ads/googleads/v12/enums/types/bidding_strategy_system_status.py create mode 100644 google/ads/googleads/v12/enums/types/bidding_strategy_type.py create mode 100644 google/ads/googleads/v12/enums/types/billing_setup_status.py create mode 100644 google/ads/googleads/v12/enums/types/brand_safety_suitability.py create mode 100644 google/ads/googleads/v12/enums/types/budget_campaign_association_status.py create mode 100644 google/ads/googleads/v12/enums/types/budget_delivery_method.py create mode 100644 google/ads/googleads/v12/enums/types/budget_period.py create mode 100644 google/ads/googleads/v12/enums/types/budget_status.py create mode 100644 google/ads/googleads/v12/enums/types/budget_type.py create mode 100644 google/ads/googleads/v12/enums/types/call_conversion_reporting_state.py create mode 100644 google/ads/googleads/v12/enums/types/call_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/call_to_action_type.py create mode 100644 google/ads/googleads/v12/enums/types/call_tracking_display_location.py create mode 100644 google/ads/googleads/v12/enums/types/call_type.py create mode 100644 google/ads/googleads/v12/enums/types/callout_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_criterion_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_draft_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_experiment_type.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_group_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_primary_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_primary_status_reason.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_serving_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_shared_set_status.py create mode 100644 google/ads/googleads/v12/enums/types/campaign_status.py create mode 100644 google/ads/googleads/v12/enums/types/chain_relationship_type.py create mode 100644 google/ads/googleads/v12/enums/types/change_client_type.py create mode 100644 google/ads/googleads/v12/enums/types/change_event_resource_type.py create mode 100644 google/ads/googleads/v12/enums/types/change_status_operation.py create mode 100644 google/ads/googleads/v12/enums/types/change_status_resource_type.py create mode 100644 google/ads/googleads/v12/enums/types/click_type.py create mode 100644 google/ads/googleads/v12/enums/types/combined_audience_status.py create mode 100644 google/ads/googleads/v12/enums/types/content_label_type.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_action_category.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_action_counting_type.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_action_status.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_action_type.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_adjustment_type.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_attribution_event_type.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_custom_variable_status.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_environment_enum.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_lag_bucket.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_or_adjustment_lag_bucket.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_origin.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_tracking_status_enum.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_value_rule_primary_dimension.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_value_rule_set_status.py create mode 100644 google/ads/googleads/v12/enums/types/conversion_value_rule_status.py create mode 100644 google/ads/googleads/v12/enums/types/criterion_category_channel_availability_mode.py create mode 100644 google/ads/googleads/v12/enums/types/criterion_category_locale_availability_mode.py create mode 100644 google/ads/googleads/v12/enums/types/criterion_system_serving_status.py create mode 100644 google/ads/googleads/v12/enums/types/criterion_type.py create mode 100644 google/ads/googleads/v12/enums/types/custom_audience_member_type.py create mode 100644 google/ads/googleads/v12/enums/types/custom_audience_status.py create mode 100644 google/ads/googleads/v12/enums/types/custom_audience_type.py create mode 100644 google/ads/googleads/v12/enums/types/custom_conversion_goal_status.py create mode 100644 google/ads/googleads/v12/enums/types/custom_interest_member_type.py create mode 100644 google/ads/googleads/v12/enums/types/custom_interest_status.py create mode 100644 google/ads/googleads/v12/enums/types/custom_interest_type.py create mode 100644 google/ads/googleads/v12/enums/types/custom_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/customer_match_upload_key_type.py create mode 100644 google/ads/googleads/v12/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py create mode 100644 google/ads/googleads/v12/enums/types/customer_status.py create mode 100644 google/ads/googleads/v12/enums/types/customizer_attribute_status.py create mode 100644 google/ads/googleads/v12/enums/types/customizer_attribute_type.py create mode 100644 google/ads/googleads/v12/enums/types/customizer_value_status.py create mode 100644 google/ads/googleads/v12/enums/types/data_driven_model_status.py create mode 100644 google/ads/googleads/v12/enums/types/day_of_week.py create mode 100644 google/ads/googleads/v12/enums/types/device.py create mode 100644 google/ads/googleads/v12/enums/types/display_ad_format_setting.py create mode 100644 google/ads/googleads/v12/enums/types/display_upload_product_type.py create mode 100644 google/ads/googleads/v12/enums/types/distance_bucket.py create mode 100644 google/ads/googleads/v12/enums/types/dsa_page_feed_criterion_field.py create mode 100644 google/ads/googleads/v12/enums/types/education_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/experiment_metric.py create mode 100644 google/ads/googleads/v12/enums/types/experiment_metric_direction.py create mode 100644 google/ads/googleads/v12/enums/types/experiment_status.py create mode 100644 google/ads/googleads/v12/enums/types/experiment_type.py create mode 100644 google/ads/googleads/v12/enums/types/extension_setting_device.py create mode 100644 google/ads/googleads/v12/enums/types/extension_type.py create mode 100644 google/ads/googleads/v12/enums/types/external_conversion_source.py create mode 100644 google/ads/googleads/v12/enums/types/feed_attribute_type.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_quality_approval_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_quality_disapproval_reason.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_set_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_set_string_filter_type.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_target_device.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_target_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_target_type.py create mode 100644 google/ads/googleads/v12/enums/types/feed_item_validation_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_mapping_criterion_type.py create mode 100644 google/ads/googleads/v12/enums/types/feed_mapping_status.py create mode 100644 google/ads/googleads/v12/enums/types/feed_origin.py create mode 100644 google/ads/googleads/v12/enums/types/feed_status.py create mode 100644 google/ads/googleads/v12/enums/types/flight_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/frequency_cap_event_type.py create mode 100644 google/ads/googleads/v12/enums/types/frequency_cap_level.py create mode 100644 google/ads/googleads/v12/enums/types/frequency_cap_time_unit.py create mode 100644 google/ads/googleads/v12/enums/types/gender_type.py create mode 100644 google/ads/googleads/v12/enums/types/geo_target_constant_status.py create mode 100644 google/ads/googleads/v12/enums/types/geo_targeting_restriction.py create mode 100644 google/ads/googleads/v12/enums/types/geo_targeting_type.py create mode 100644 google/ads/googleads/v12/enums/types/goal_config_level.py create mode 100644 google/ads/googleads/v12/enums/types/google_ads_field_category.py create mode 100644 google/ads/googleads/v12/enums/types/google_ads_field_data_type.py create mode 100644 google/ads/googleads/v12/enums/types/google_voice_call_status.py create mode 100644 google/ads/googleads/v12/enums/types/hotel_date_selection_type.py create mode 100644 google/ads/googleads/v12/enums/types/hotel_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/hotel_price_bucket.py create mode 100644 google/ads/googleads/v12/enums/types/hotel_rate_type.py create mode 100644 google/ads/googleads/v12/enums/types/hotel_reconciliation_status.py create mode 100644 google/ads/googleads/v12/enums/types/image_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/income_range_type.py create mode 100644 google/ads/googleads/v12/enums/types/interaction_event_type.py create mode 100644 google/ads/googleads/v12/enums/types/interaction_type.py create mode 100644 google/ads/googleads/v12/enums/types/invoice_type.py create mode 100644 google/ads/googleads/v12/enums/types/job_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_match_type.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_aggregate_metric_type.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_competition_level.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_concept_group_type.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_forecast_interval.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_keyword_annotation.py create mode 100644 google/ads/googleads/v12/enums/types/keyword_plan_network.py create mode 100644 google/ads/googleads/v12/enums/types/label_status.py create mode 100644 google/ads/googleads/v12/enums/types/lead_form_call_to_action_type.py create mode 100644 google/ads/googleads/v12/enums/types/lead_form_desired_intent.py create mode 100644 google/ads/googleads/v12/enums/types/lead_form_field_user_input_type.py create mode 100644 google/ads/googleads/v12/enums/types/lead_form_post_submit_call_to_action_type.py create mode 100644 google/ads/googleads/v12/enums/types/legacy_app_install_ad_app_store.py create mode 100644 google/ads/googleads/v12/enums/types/linked_account_type.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_bidding_category_level.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_custom_attribute_index.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_product_channel.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_product_condition.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_product_type_level.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_type_enum.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_filter_vertical.py create mode 100644 google/ads/googleads/v12/enums/types/listing_group_type.py create mode 100644 google/ads/googleads/v12/enums/types/local_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/location_extension_targeting_criterion_field.py create mode 100644 google/ads/googleads/v12/enums/types/location_group_radius_units.py create mode 100644 google/ads/googleads/v12/enums/types/location_ownership_type.py create mode 100644 google/ads/googleads/v12/enums/types/location_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/location_source_type.py create mode 100644 google/ads/googleads/v12/enums/types/location_string_filter_type.py create mode 100644 google/ads/googleads/v12/enums/types/manager_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/matching_function_context_type.py create mode 100644 google/ads/googleads/v12/enums/types/matching_function_operator.py create mode 100644 google/ads/googleads/v12/enums/types/media_type.py create mode 100644 google/ads/googleads/v12/enums/types/merchant_center_link_status.py create mode 100644 google/ads/googleads/v12/enums/types/message_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/mime_type.py create mode 100644 google/ads/googleads/v12/enums/types/minute_of_hour.py create mode 100644 google/ads/googleads/v12/enums/types/mobile_app_vendor.py create mode 100644 google/ads/googleads/v12/enums/types/mobile_device_type.py create mode 100644 google/ads/googleads/v12/enums/types/month_of_year.py create mode 100644 google/ads/googleads/v12/enums/types/negative_geo_target_type.py create mode 100644 google/ads/googleads/v12/enums/types/offline_user_data_job_failure_reason.py create mode 100644 google/ads/googleads/v12/enums/types/offline_user_data_job_match_rate_range.py create mode 100644 google/ads/googleads/v12/enums/types/offline_user_data_job_status.py create mode 100644 google/ads/googleads/v12/enums/types/offline_user_data_job_type.py create mode 100644 google/ads/googleads/v12/enums/types/operating_system_version_operator_type.py create mode 100644 google/ads/googleads/v12/enums/types/optimization_goal_type.py create mode 100644 google/ads/googleads/v12/enums/types/parental_status_type.py create mode 100644 google/ads/googleads/v12/enums/types/payment_mode.py create mode 100644 google/ads/googleads/v12/enums/types/performance_max_upgrade_status.py create mode 100644 google/ads/googleads/v12/enums/types/placeholder_type.py create mode 100644 google/ads/googleads/v12/enums/types/placement_type.py create mode 100644 google/ads/googleads/v12/enums/types/policy_approval_status.py create mode 100644 google/ads/googleads/v12/enums/types/policy_review_status.py create mode 100644 google/ads/googleads/v12/enums/types/policy_topic_entry_type.py create mode 100644 google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_mismatch_url_type.py create mode 100644 google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_device.py create mode 100644 google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py create mode 100644 google/ads/googleads/v12/enums/types/positive_geo_target_type.py create mode 100644 google/ads/googleads/v12/enums/types/preferred_content_type.py create mode 100644 google/ads/googleads/v12/enums/types/price_extension_price_qualifier.py create mode 100644 google/ads/googleads/v12/enums/types/price_extension_price_unit.py create mode 100644 google/ads/googleads/v12/enums/types/price_extension_type.py create mode 100644 google/ads/googleads/v12/enums/types/price_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/product_bidding_category_level.py create mode 100644 google/ads/googleads/v12/enums/types/product_bidding_category_status.py create mode 100644 google/ads/googleads/v12/enums/types/product_channel.py create mode 100644 google/ads/googleads/v12/enums/types/product_channel_exclusivity.py create mode 100644 google/ads/googleads/v12/enums/types/product_condition.py create mode 100644 google/ads/googleads/v12/enums/types/product_custom_attribute_index.py create mode 100644 google/ads/googleads/v12/enums/types/product_type_level.py create mode 100644 google/ads/googleads/v12/enums/types/promotion_extension_discount_modifier.py create mode 100644 google/ads/googleads/v12/enums/types/promotion_extension_occasion.py create mode 100644 google/ads/googleads/v12/enums/types/promotion_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/proximity_radius_units.py create mode 100644 google/ads/googleads/v12/enums/types/quality_score_bucket.py create mode 100644 google/ads/googleads/v12/enums/types/reach_plan_age_range.py create mode 100644 google/ads/googleads/v12/enums/types/reach_plan_network.py create mode 100644 google/ads/googleads/v12/enums/types/real_estate_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/recommendation_type.py create mode 100644 google/ads/googleads/v12/enums/types/resource_change_operation.py create mode 100644 google/ads/googleads/v12/enums/types/resource_limit_type.py create mode 100644 google/ads/googleads/v12/enums/types/response_content_type.py create mode 100644 google/ads/googleads/v12/enums/types/search_engine_results_page_type.py create mode 100644 google/ads/googleads/v12/enums/types/search_term_match_type.py create mode 100644 google/ads/googleads/v12/enums/types/search_term_targeting_status.py create mode 100644 google/ads/googleads/v12/enums/types/seasonality_event_scope.py create mode 100644 google/ads/googleads/v12/enums/types/seasonality_event_status.py create mode 100644 google/ads/googleads/v12/enums/types/served_asset_field_type.py create mode 100644 google/ads/googleads/v12/enums/types/shared_set_status.py create mode 100644 google/ads/googleads/v12/enums/types/shared_set_type.py create mode 100644 google/ads/googleads/v12/enums/types/simulation_modification_method.py create mode 100644 google/ads/googleads/v12/enums/types/simulation_type.py create mode 100644 google/ads/googleads/v12/enums/types/sitelink_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/sk_ad_network_ad_event_type.py create mode 100644 google/ads/googleads/v12/enums/types/sk_ad_network_attribution_credit.py create mode 100644 google/ads/googleads/v12/enums/types/sk_ad_network_user_type.py create mode 100644 google/ads/googleads/v12/enums/types/slot.py create mode 100644 google/ads/googleads/v12/enums/types/spending_limit_type.py create mode 100644 google/ads/googleads/v12/enums/types/structured_snippet_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/summary_row_setting.py create mode 100644 google/ads/googleads/v12/enums/types/system_managed_entity_source.py create mode 100644 google/ads/googleads/v12/enums/types/target_cpa_opt_in_recommendation_goal.py create mode 100644 google/ads/googleads/v12/enums/types/target_impression_share_location.py create mode 100644 google/ads/googleads/v12/enums/types/targeting_dimension.py create mode 100644 google/ads/googleads/v12/enums/types/time_type.py create mode 100644 google/ads/googleads/v12/enums/types/tracking_code_page_format.py create mode 100644 google/ads/googleads/v12/enums/types/tracking_code_type.py create mode 100644 google/ads/googleads/v12/enums/types/travel_placeholder_field.py create mode 100644 google/ads/googleads/v12/enums/types/user_identifier_source.py create mode 100644 google/ads/googleads/v12/enums/types/user_interest_taxonomy_type.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_access_status.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_closing_reason.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_combined_rule_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_crm_data_source_type.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_date_rule_item_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_flexible_rule_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_logical_rule_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_membership_status.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_number_rule_item_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_prepopulation_status.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_rule_type.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_size_range.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_string_rule_item_operator.py create mode 100644 google/ads/googleads/v12/enums/types/user_list_type.py create mode 100644 google/ads/googleads/v12/enums/types/value_rule_device_type.py create mode 100644 google/ads/googleads/v12/enums/types/value_rule_geo_location_match_type.py create mode 100644 google/ads/googleads/v12/enums/types/value_rule_operation.py create mode 100644 google/ads/googleads/v12/enums/types/value_rule_set_attachment_type.py create mode 100644 google/ads/googleads/v12/enums/types/value_rule_set_dimension.py create mode 100644 google/ads/googleads/v12/enums/types/vanity_pharma_display_url_mode.py create mode 100644 google/ads/googleads/v12/enums/types/vanity_pharma_text.py create mode 100644 google/ads/googleads/v12/enums/types/video_thumbnail.py create mode 100644 google/ads/googleads/v12/enums/types/webpage_condition_operand.py create mode 100644 google/ads/googleads/v12/enums/types/webpage_condition_operator.py create mode 100644 google/ads/googleads/v12/errors/__init__.py create mode 100644 google/ads/googleads/v12/errors/services/__init__.py create mode 100644 google/ads/googleads/v12/errors/types/__init__.py create mode 100644 google/ads/googleads/v12/errors/types/access_invitation_error.py create mode 100644 google/ads/googleads/v12/errors/types/account_budget_proposal_error.py create mode 100644 google/ads/googleads/v12/errors/types/account_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_customizer_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_ad_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_bid_modifier_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_criterion_customizer_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_criterion_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_customizer_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_group_feed_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_parameter_error.py create mode 100644 google/ads/googleads/v12/errors/types/ad_sharing_error.py create mode 100644 google/ads/googleads/v12/errors/types/adx_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_group_asset_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_group_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_group_listing_group_filter_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_set_asset_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_set_error.py create mode 100644 google/ads/googleads/v12/errors/types/asset_set_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/audience_error.py create mode 100644 google/ads/googleads/v12/errors/types/audience_insights_error.py create mode 100644 google/ads/googleads/v12/errors/types/authentication_error.py create mode 100644 google/ads/googleads/v12/errors/types/authorization_error.py create mode 100644 google/ads/googleads/v12/errors/types/batch_job_error.py create mode 100644 google/ads/googleads/v12/errors/types/bidding_error.py create mode 100644 google/ads/googleads/v12/errors/types/bidding_strategy_error.py create mode 100644 google/ads/googleads/v12/errors/types/billing_setup_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_budget_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_conversion_goal_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_criterion_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_customizer_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_draft_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_experiment_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_feed_error.py create mode 100644 google/ads/googleads/v12/errors/types/campaign_shared_set_error.py create mode 100644 google/ads/googleads/v12/errors/types/change_event_error.py create mode 100644 google/ads/googleads/v12/errors/types/change_status_error.py create mode 100644 google/ads/googleads/v12/errors/types/collection_size_error.py create mode 100644 google/ads/googleads/v12/errors/types/context_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_action_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_adjustment_upload_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_custom_variable_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_goal_campaign_config_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_upload_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_value_rule_error.py create mode 100644 google/ads/googleads/v12/errors/types/conversion_value_rule_set_error.py create mode 100644 google/ads/googleads/v12/errors/types/country_code_error.py create mode 100644 google/ads/googleads/v12/errors/types/criterion_error.py create mode 100644 google/ads/googleads/v12/errors/types/currency_code_error.py create mode 100644 google/ads/googleads/v12/errors/types/custom_audience_error.py create mode 100644 google/ads/googleads/v12/errors/types/custom_conversion_goal_error.py create mode 100644 google/ads/googleads/v12/errors/types/custom_interest_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_client_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_customizer_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_feed_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_manager_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/customer_user_access_error.py create mode 100644 google/ads/googleads/v12/errors/types/customizer_attribute_error.py create mode 100644 google/ads/googleads/v12/errors/types/database_error.py create mode 100644 google/ads/googleads/v12/errors/types/date_error.py create mode 100644 google/ads/googleads/v12/errors/types/date_range_error.py create mode 100644 google/ads/googleads/v12/errors/types/distinct_error.py create mode 100644 google/ads/googleads/v12/errors/types/enum_error.py create mode 100644 google/ads/googleads/v12/errors/types/errors.py create mode 100644 google/ads/googleads/v12/errors/types/experiment_arm_error.py create mode 100644 google/ads/googleads/v12/errors/types/experiment_error.py create mode 100644 google/ads/googleads/v12/errors/types/extension_feed_item_error.py create mode 100644 google/ads/googleads/v12/errors/types/extension_setting_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_attribute_reference_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_item_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_item_set_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_item_set_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_item_target_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_item_validation_error.py create mode 100644 google/ads/googleads/v12/errors/types/feed_mapping_error.py create mode 100644 google/ads/googleads/v12/errors/types/field_error.py create mode 100644 google/ads/googleads/v12/errors/types/field_mask_error.py create mode 100644 google/ads/googleads/v12/errors/types/function_error.py create mode 100644 google/ads/googleads/v12/errors/types/function_parsing_error.py create mode 100644 google/ads/googleads/v12/errors/types/geo_target_constant_suggestion_error.py create mode 100644 google/ads/googleads/v12/errors/types/header_error.py create mode 100644 google/ads/googleads/v12/errors/types/id_error.py create mode 100644 google/ads/googleads/v12/errors/types/image_error.py create mode 100644 google/ads/googleads/v12/errors/types/internal_error.py create mode 100644 google/ads/googleads/v12/errors/types/invoice_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_ad_group_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_ad_group_keyword_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_campaign_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_campaign_keyword_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_error.py create mode 100644 google/ads/googleads/v12/errors/types/keyword_plan_idea_error.py create mode 100644 google/ads/googleads/v12/errors/types/label_error.py create mode 100644 google/ads/googleads/v12/errors/types/language_code_error.py create mode 100644 google/ads/googleads/v12/errors/types/list_operation_error.py create mode 100644 google/ads/googleads/v12/errors/types/manager_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/media_bundle_error.py create mode 100644 google/ads/googleads/v12/errors/types/media_file_error.py create mode 100644 google/ads/googleads/v12/errors/types/media_upload_error.py create mode 100644 google/ads/googleads/v12/errors/types/merchant_center_error.py create mode 100644 google/ads/googleads/v12/errors/types/multiplier_error.py create mode 100644 google/ads/googleads/v12/errors/types/mutate_error.py create mode 100644 google/ads/googleads/v12/errors/types/new_resource_creation_error.py create mode 100644 google/ads/googleads/v12/errors/types/not_allowlisted_error.py create mode 100644 google/ads/googleads/v12/errors/types/not_empty_error.py create mode 100644 google/ads/googleads/v12/errors/types/null_error.py create mode 100644 google/ads/googleads/v12/errors/types/offline_user_data_job_error.py create mode 100644 google/ads/googleads/v12/errors/types/operation_access_denied_error.py create mode 100644 google/ads/googleads/v12/errors/types/operator_error.py create mode 100644 google/ads/googleads/v12/errors/types/partial_failure_error.py create mode 100644 google/ads/googleads/v12/errors/types/payments_account_error.py create mode 100644 google/ads/googleads/v12/errors/types/policy_finding_error.py create mode 100644 google/ads/googleads/v12/errors/types/policy_validation_parameter_error.py create mode 100644 google/ads/googleads/v12/errors/types/policy_violation_error.py create mode 100644 google/ads/googleads/v12/errors/types/query_error.py create mode 100644 google/ads/googleads/v12/errors/types/quota_error.py create mode 100644 google/ads/googleads/v12/errors/types/range_error.py create mode 100644 google/ads/googleads/v12/errors/types/reach_plan_error.py create mode 100644 google/ads/googleads/v12/errors/types/recommendation_error.py create mode 100644 google/ads/googleads/v12/errors/types/region_code_error.py create mode 100644 google/ads/googleads/v12/errors/types/request_error.py create mode 100644 google/ads/googleads/v12/errors/types/resource_access_denied_error.py create mode 100644 google/ads/googleads/v12/errors/types/resource_count_limit_exceeded_error.py create mode 100644 google/ads/googleads/v12/errors/types/setting_error.py create mode 100644 google/ads/googleads/v12/errors/types/shared_criterion_error.py create mode 100644 google/ads/googleads/v12/errors/types/shared_set_error.py create mode 100644 google/ads/googleads/v12/errors/types/size_limit_error.py create mode 100644 google/ads/googleads/v12/errors/types/smart_campaign_error.py create mode 100644 google/ads/googleads/v12/errors/types/string_format_error.py create mode 100644 google/ads/googleads/v12/errors/types/string_length_error.py create mode 100644 google/ads/googleads/v12/errors/types/third_party_app_analytics_link_error.py create mode 100644 google/ads/googleads/v12/errors/types/time_zone_error.py create mode 100644 google/ads/googleads/v12/errors/types/url_field_error.py create mode 100644 google/ads/googleads/v12/errors/types/user_data_error.py create mode 100644 google/ads/googleads/v12/errors/types/user_list_error.py create mode 100644 google/ads/googleads/v12/errors/types/youtube_video_registration_error.py create mode 100644 google/ads/googleads/v12/resources/__init__.py create mode 100644 google/ads/googleads/v12/resources/services/__init__.py create mode 100644 google/ads/googleads/v12/resources/types/__init__.py create mode 100644 google/ads/googleads/v12/resources/types/accessible_bidding_strategy.py create mode 100644 google/ads/googleads/v12/resources/types/account_budget.py create mode 100644 google/ads/googleads/v12/resources/types/account_budget_proposal.py create mode 100644 google/ads/googleads/v12/resources/types/account_link.py create mode 100644 google/ads/googleads/v12/resources/types/ad.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_ad.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_ad_asset_combination_view.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_ad_asset_view.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_ad_label.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_asset.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_asset_set.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_audience_view.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_bid_modifier.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_criterion.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_criterion_customizer.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_criterion_label.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_criterion_simulation.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_customizer.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_extension_setting.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_feed.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_label.py create mode 100644 google/ads/googleads/v12/resources/types/ad_group_simulation.py create mode 100644 google/ads/googleads/v12/resources/types/ad_parameter.py create mode 100644 google/ads/googleads/v12/resources/types/ad_schedule_view.py create mode 100644 google/ads/googleads/v12/resources/types/age_range_view.py create mode 100644 google/ads/googleads/v12/resources/types/asset.py create mode 100644 google/ads/googleads/v12/resources/types/asset_field_type_view.py create mode 100644 google/ads/googleads/v12/resources/types/asset_group.py create mode 100644 google/ads/googleads/v12/resources/types/asset_group_asset.py create mode 100644 google/ads/googleads/v12/resources/types/asset_group_listing_group_filter.py create mode 100644 google/ads/googleads/v12/resources/types/asset_group_product_group_view.py create mode 100644 google/ads/googleads/v12/resources/types/asset_group_signal.py create mode 100644 google/ads/googleads/v12/resources/types/asset_set.py create mode 100644 google/ads/googleads/v12/resources/types/asset_set_asset.py create mode 100644 google/ads/googleads/v12/resources/types/asset_set_type_view.py create mode 100644 google/ads/googleads/v12/resources/types/audience.py create mode 100644 google/ads/googleads/v12/resources/types/batch_job.py create mode 100644 google/ads/googleads/v12/resources/types/bidding_data_exclusion.py create mode 100644 google/ads/googleads/v12/resources/types/bidding_seasonality_adjustment.py create mode 100644 google/ads/googleads/v12/resources/types/bidding_strategy.py create mode 100644 google/ads/googleads/v12/resources/types/bidding_strategy_simulation.py create mode 100644 google/ads/googleads/v12/resources/types/billing_setup.py create mode 100644 google/ads/googleads/v12/resources/types/call_view.py create mode 100644 google/ads/googleads/v12/resources/types/campaign.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_asset.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_asset_set.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_audience_view.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_bid_modifier.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_budget.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_conversion_goal.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_criterion.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_criterion_simulation.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_customizer.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_draft.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_extension_setting.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_feed.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_group.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_label.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_shared_set.py create mode 100644 google/ads/googleads/v12/resources/types/campaign_simulation.py create mode 100644 google/ads/googleads/v12/resources/types/carrier_constant.py create mode 100644 google/ads/googleads/v12/resources/types/change_event.py create mode 100644 google/ads/googleads/v12/resources/types/change_status.py create mode 100644 google/ads/googleads/v12/resources/types/click_view.py create mode 100644 google/ads/googleads/v12/resources/types/combined_audience.py create mode 100644 google/ads/googleads/v12/resources/types/conversion_action.py create mode 100644 google/ads/googleads/v12/resources/types/conversion_custom_variable.py create mode 100644 google/ads/googleads/v12/resources/types/conversion_goal_campaign_config.py create mode 100644 google/ads/googleads/v12/resources/types/conversion_value_rule.py create mode 100644 google/ads/googleads/v12/resources/types/conversion_value_rule_set.py create mode 100644 google/ads/googleads/v12/resources/types/currency_constant.py create mode 100644 google/ads/googleads/v12/resources/types/custom_audience.py create mode 100644 google/ads/googleads/v12/resources/types/custom_conversion_goal.py create mode 100644 google/ads/googleads/v12/resources/types/custom_interest.py create mode 100644 google/ads/googleads/v12/resources/types/customer.py create mode 100644 google/ads/googleads/v12/resources/types/customer_asset.py create mode 100644 google/ads/googleads/v12/resources/types/customer_asset_set.py create mode 100644 google/ads/googleads/v12/resources/types/customer_client.py create mode 100644 google/ads/googleads/v12/resources/types/customer_client_link.py create mode 100644 google/ads/googleads/v12/resources/types/customer_conversion_goal.py create mode 100644 google/ads/googleads/v12/resources/types/customer_customizer.py create mode 100644 google/ads/googleads/v12/resources/types/customer_extension_setting.py create mode 100644 google/ads/googleads/v12/resources/types/customer_feed.py create mode 100644 google/ads/googleads/v12/resources/types/customer_label.py create mode 100644 google/ads/googleads/v12/resources/types/customer_manager_link.py create mode 100644 google/ads/googleads/v12/resources/types/customer_negative_criterion.py create mode 100644 google/ads/googleads/v12/resources/types/customer_user_access.py create mode 100644 google/ads/googleads/v12/resources/types/customer_user_access_invitation.py create mode 100644 google/ads/googleads/v12/resources/types/customizer_attribute.py create mode 100644 google/ads/googleads/v12/resources/types/detail_placement_view.py create mode 100644 google/ads/googleads/v12/resources/types/detailed_demographic.py create mode 100644 google/ads/googleads/v12/resources/types/display_keyword_view.py create mode 100644 google/ads/googleads/v12/resources/types/distance_view.py create mode 100644 google/ads/googleads/v12/resources/types/domain_category.py create mode 100644 google/ads/googleads/v12/resources/types/dynamic_search_ads_search_term_view.py create mode 100644 google/ads/googleads/v12/resources/types/expanded_landing_page_view.py create mode 100644 google/ads/googleads/v12/resources/types/experiment.py create mode 100644 google/ads/googleads/v12/resources/types/experiment_arm.py create mode 100644 google/ads/googleads/v12/resources/types/extension_feed_item.py create mode 100644 google/ads/googleads/v12/resources/types/feed.py create mode 100644 google/ads/googleads/v12/resources/types/feed_item.py create mode 100644 google/ads/googleads/v12/resources/types/feed_item_set.py create mode 100644 google/ads/googleads/v12/resources/types/feed_item_set_link.py create mode 100644 google/ads/googleads/v12/resources/types/feed_item_target.py create mode 100644 google/ads/googleads/v12/resources/types/feed_mapping.py create mode 100644 google/ads/googleads/v12/resources/types/feed_placeholder_view.py create mode 100644 google/ads/googleads/v12/resources/types/gender_view.py create mode 100644 google/ads/googleads/v12/resources/types/geo_target_constant.py create mode 100644 google/ads/googleads/v12/resources/types/geographic_view.py create mode 100644 google/ads/googleads/v12/resources/types/google_ads_field.py create mode 100644 google/ads/googleads/v12/resources/types/group_placement_view.py create mode 100644 google/ads/googleads/v12/resources/types/hotel_group_view.py create mode 100644 google/ads/googleads/v12/resources/types/hotel_performance_view.py create mode 100644 google/ads/googleads/v12/resources/types/hotel_reconciliation.py create mode 100644 google/ads/googleads/v12/resources/types/income_range_view.py create mode 100644 google/ads/googleads/v12/resources/types/invoice.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_plan.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_plan_ad_group.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_plan_ad_group_keyword.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_plan_campaign.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_plan_campaign_keyword.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_theme_constant.py create mode 100644 google/ads/googleads/v12/resources/types/keyword_view.py create mode 100644 google/ads/googleads/v12/resources/types/label.py create mode 100644 google/ads/googleads/v12/resources/types/landing_page_view.py create mode 100644 google/ads/googleads/v12/resources/types/language_constant.py create mode 100644 google/ads/googleads/v12/resources/types/lead_form_submission_data.py create mode 100644 google/ads/googleads/v12/resources/types/life_event.py create mode 100644 google/ads/googleads/v12/resources/types/location_view.py create mode 100644 google/ads/googleads/v12/resources/types/managed_placement_view.py create mode 100644 google/ads/googleads/v12/resources/types/media_file.py create mode 100644 google/ads/googleads/v12/resources/types/merchant_center_link.py create mode 100644 google/ads/googleads/v12/resources/types/mobile_app_category_constant.py create mode 100644 google/ads/googleads/v12/resources/types/mobile_device_constant.py create mode 100644 google/ads/googleads/v12/resources/types/offline_user_data_job.py create mode 100644 google/ads/googleads/v12/resources/types/operating_system_version_constant.py create mode 100644 google/ads/googleads/v12/resources/types/paid_organic_search_term_view.py create mode 100644 google/ads/googleads/v12/resources/types/parental_status_view.py create mode 100644 google/ads/googleads/v12/resources/types/payments_account.py create mode 100644 google/ads/googleads/v12/resources/types/per_store_view.py create mode 100644 google/ads/googleads/v12/resources/types/product_bidding_category_constant.py create mode 100644 google/ads/googleads/v12/resources/types/product_group_view.py create mode 100644 google/ads/googleads/v12/resources/types/recommendation.py create mode 100644 google/ads/googleads/v12/resources/types/remarketing_action.py create mode 100644 google/ads/googleads/v12/resources/types/search_term_view.py create mode 100644 google/ads/googleads/v12/resources/types/shared_criterion.py create mode 100644 google/ads/googleads/v12/resources/types/shared_set.py create mode 100644 google/ads/googleads/v12/resources/types/shopping_performance_view.py create mode 100644 google/ads/googleads/v12/resources/types/smart_campaign_search_term_view.py create mode 100644 google/ads/googleads/v12/resources/types/smart_campaign_setting.py create mode 100644 google/ads/googleads/v12/resources/types/third_party_app_analytics_link.py create mode 100644 google/ads/googleads/v12/resources/types/topic_constant.py create mode 100644 google/ads/googleads/v12/resources/types/topic_view.py create mode 100644 google/ads/googleads/v12/resources/types/user_interest.py create mode 100644 google/ads/googleads/v12/resources/types/user_list.py create mode 100644 google/ads/googleads/v12/resources/types/user_location_view.py create mode 100644 google/ads/googleads/v12/resources/types/video.py create mode 100644 google/ads/googleads/v12/resources/types/webpage_view.py create mode 100644 google/ads/googleads/v12/services/__init__.py create mode 100644 google/ads/googleads/v12/services/services/__init__.py create mode 100644 google/ads/googleads/v12/services/services/account_budget_proposal_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/account_budget_proposal_service/client.py create mode 100644 google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/account_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/account_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/account_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/account_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/account_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_ad_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_customizer_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_customizer_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_extension_setting_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_extension_setting_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_feed_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_feed_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_feed_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_feed_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_feed_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_group_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_parameter_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_parameter_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_parameter_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_parameter_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_parameter_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/ad_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_service/client.py create mode 100644 google/ads/googleads/v12/services/services/ad_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/ad_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/ad_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_signal_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_signal_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_signal_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_signal_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_group_signal_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/asset_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/audience_insights_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/audience_insights_service/client.py create mode 100644 google/ads/googleads/v12/services/services/audience_insights_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/audience_insights_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/audience_insights_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/audience_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/audience_service/client.py create mode 100644 google/ads/googleads/v12/services/services/audience_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/audience_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/audience_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/client.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/batch_job_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/bidding_data_exclusion_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_data_exclusion_service/client.py create mode 100644 google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/client.py create mode 100644 google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/bidding_strategy_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_strategy_service/client.py create mode 100644 google/ads/googleads/v12/services/services/bidding_strategy_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/bidding_strategy_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/bidding_strategy_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/billing_setup_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/billing_setup_service/client.py create mode 100644 google/ads/googleads/v12/services/services/billing_setup_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/billing_setup_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/billing_setup_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_bid_modifier_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_bid_modifier_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_budget_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_budget_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_budget_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_budget_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_budget_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_conversion_goal_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_conversion_goal_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_criterion_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_criterion_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_criterion_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_criterion_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_criterion_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_customizer_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_customizer_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_customizer_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_customizer_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_customizer_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_draft_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_extension_setting_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_extension_setting_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_feed_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_feed_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_feed_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_feed_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_feed_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_group_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_group_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_group_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_group_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_group_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/campaign_shared_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_shared_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_action_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_action_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_action_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_action_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_action_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_custom_variable_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_custom_variable_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_upload_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_upload_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_upload_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_upload_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_upload_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/custom_audience_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_audience_service/client.py create mode 100644 google/ads/googleads/v12/services/services/custom_audience_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_audience_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/custom_audience_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/custom_conversion_goal_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_conversion_goal_service/client.py create mode 100644 google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/custom_interest_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_interest_service/client.py create mode 100644 google/ads/googleads/v12/services/services/custom_interest_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/custom_interest_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/custom_interest_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_asset_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_client_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_client_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_client_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_client_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_client_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_conversion_goal_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_conversion_goal_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_customizer_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_customizer_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_customizer_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_customizer_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_customizer_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_extension_setting_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_extension_setting_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_feed_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_feed_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_feed_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_feed_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_feed_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_manager_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_manager_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_manager_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_manager_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_manager_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_negative_criterion_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_negative_criterion_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_invitation_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_invitation_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customer_user_access_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/customizer_attribute_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customizer_attribute_service/client.py create mode 100644 google/ads/googleads/v12/services/services/customizer_attribute_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/customizer_attribute_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/customizer_attribute_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/experiment_arm_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/experiment_arm_service/client.py create mode 100644 google/ads/googleads/v12/services/services/experiment_arm_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/experiment_arm_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/experiment_arm_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/client.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/experiment_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/extension_feed_item_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/extension_feed_item_service/client.py create mode 100644 google/ads/googleads/v12/services/services/extension_feed_item_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/extension_feed_item_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/extension_feed_item_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_target_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_target_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_target_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_target_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_item_target_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_mapping_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_mapping_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_mapping_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_mapping_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_mapping_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/feed_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_service/client.py create mode 100644 google/ads/googleads/v12/services/services/feed_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/feed_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/feed_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/geo_target_constant_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/geo_target_constant_service/client.py create mode 100644 google/ads/googleads/v12/services/services/geo_target_constant_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/geo_target_constant_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/geo_target_constant_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/client.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_field_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/client.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/google_ads_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/invoice_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/invoice_service/client.py create mode 100644 google/ads/googleads/v12/services/services/invoice_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/invoice_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/invoice_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/pagers.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_plan_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/keyword_theme_constant_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_theme_constant_service/client.py create mode 100644 google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/label_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/label_service/client.py create mode 100644 google/ads/googleads/v12/services/services/label_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/label_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/label_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/media_file_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/media_file_service/client.py create mode 100644 google/ads/googleads/v12/services/services/media_file_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/media_file_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/media_file_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/merchant_center_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/merchant_center_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/merchant_center_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/merchant_center_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/merchant_center_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/offline_user_data_job_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/offline_user_data_job_service/client.py create mode 100644 google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/payments_account_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/payments_account_service/client.py create mode 100644 google/ads/googleads/v12/services/services/payments_account_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/payments_account_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/payments_account_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/reach_plan_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/reach_plan_service/client.py create mode 100644 google/ads/googleads/v12/services/services/reach_plan_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/reach_plan_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/reach_plan_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/recommendation_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/recommendation_service/client.py create mode 100644 google/ads/googleads/v12/services/services/recommendation_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/recommendation_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/recommendation_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/remarketing_action_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/remarketing_action_service/client.py create mode 100644 google/ads/googleads/v12/services/services/remarketing_action_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/remarketing_action_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/remarketing_action_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/shared_criterion_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/shared_criterion_service/client.py create mode 100644 google/ads/googleads/v12/services/services/shared_criterion_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/shared_criterion_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/shared_criterion_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/shared_set_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/shared_set_service/client.py create mode 100644 google/ads/googleads/v12/services/services/shared_set_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/shared_set_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/shared_set_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_setting_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_setting_service/client.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_suggest_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_suggest_service/client.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/client.py create mode 100644 google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/user_data_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/user_data_service/client.py create mode 100644 google/ads/googleads/v12/services/services/user_data_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/user_data_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/user_data_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/services/user_list_service/__init__.py create mode 100644 google/ads/googleads/v12/services/services/user_list_service/client.py create mode 100644 google/ads/googleads/v12/services/services/user_list_service/transports/__init__.py create mode 100644 google/ads/googleads/v12/services/services/user_list_service/transports/base.py create mode 100644 google/ads/googleads/v12/services/services/user_list_service/transports/grpc.py create mode 100644 google/ads/googleads/v12/services/types/__init__.py create mode 100644 google/ads/googleads/v12/services/types/account_budget_proposal_service.py create mode 100644 google/ads/googleads/v12/services/types/account_link_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_ad_label_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_ad_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_asset_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_asset_set_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_bid_modifier_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_criterion_customizer_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_criterion_label_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_criterion_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_customizer_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_extension_setting_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_feed_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_label_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_group_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_parameter_service.py create mode 100644 google/ads/googleads/v12/services/types/ad_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_group_asset_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_group_listing_group_filter_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_group_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_group_signal_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_set_asset_service.py create mode 100644 google/ads/googleads/v12/services/types/asset_set_service.py create mode 100644 google/ads/googleads/v12/services/types/audience_insights_service.py create mode 100644 google/ads/googleads/v12/services/types/audience_service.py create mode 100644 google/ads/googleads/v12/services/types/batch_job_service.py create mode 100644 google/ads/googleads/v12/services/types/bidding_data_exclusion_service.py create mode 100644 google/ads/googleads/v12/services/types/bidding_seasonality_adjustment_service.py create mode 100644 google/ads/googleads/v12/services/types/bidding_strategy_service.py create mode 100644 google/ads/googleads/v12/services/types/billing_setup_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_asset_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_asset_set_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_bid_modifier_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_budget_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_conversion_goal_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_criterion_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_customizer_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_draft_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_extension_setting_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_feed_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_group_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_label_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_service.py create mode 100644 google/ads/googleads/v12/services/types/campaign_shared_set_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_action_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_adjustment_upload_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_custom_variable_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_goal_campaign_config_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_upload_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_value_rule_service.py create mode 100644 google/ads/googleads/v12/services/types/conversion_value_rule_set_service.py create mode 100644 google/ads/googleads/v12/services/types/custom_audience_service.py create mode 100644 google/ads/googleads/v12/services/types/custom_conversion_goal_service.py create mode 100644 google/ads/googleads/v12/services/types/custom_interest_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_asset_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_asset_set_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_client_link_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_conversion_goal_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_customizer_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_extension_setting_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_feed_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_label_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_manager_link_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_negative_criterion_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_user_access_invitation_service.py create mode 100644 google/ads/googleads/v12/services/types/customer_user_access_service.py create mode 100644 google/ads/googleads/v12/services/types/customizer_attribute_service.py create mode 100644 google/ads/googleads/v12/services/types/experiment_arm_service.py create mode 100644 google/ads/googleads/v12/services/types/experiment_service.py create mode 100644 google/ads/googleads/v12/services/types/extension_feed_item_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_item_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_item_set_link_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_item_set_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_item_target_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_mapping_service.py create mode 100644 google/ads/googleads/v12/services/types/feed_service.py create mode 100644 google/ads/googleads/v12/services/types/geo_target_constant_service.py create mode 100644 google/ads/googleads/v12/services/types/google_ads_field_service.py create mode 100644 google/ads/googleads/v12/services/types/google_ads_service.py create mode 100644 google/ads/googleads/v12/services/types/invoice_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_ad_group_keyword_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_ad_group_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_campaign_keyword_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_campaign_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_idea_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_plan_service.py create mode 100644 google/ads/googleads/v12/services/types/keyword_theme_constant_service.py create mode 100644 google/ads/googleads/v12/services/types/label_service.py create mode 100644 google/ads/googleads/v12/services/types/media_file_service.py create mode 100644 google/ads/googleads/v12/services/types/merchant_center_link_service.py create mode 100644 google/ads/googleads/v12/services/types/offline_user_data_job_service.py create mode 100644 google/ads/googleads/v12/services/types/payments_account_service.py create mode 100644 google/ads/googleads/v12/services/types/reach_plan_service.py create mode 100644 google/ads/googleads/v12/services/types/recommendation_service.py create mode 100644 google/ads/googleads/v12/services/types/remarketing_action_service.py create mode 100644 google/ads/googleads/v12/services/types/shared_criterion_service.py create mode 100644 google/ads/googleads/v12/services/types/shared_set_service.py create mode 100644 google/ads/googleads/v12/services/types/smart_campaign_setting_service.py create mode 100644 google/ads/googleads/v12/services/types/smart_campaign_suggest_service.py create mode 100644 google/ads/googleads/v12/services/types/third_party_app_analytics_link_service.py create mode 100644 google/ads/googleads/v12/services/types/user_data_service.py create mode 100644 google/ads/googleads/v12/services/types/user_list_service.py create mode 100644 google/ads/googleads/v12/types/__init__.py diff --git a/ChangeLog b/ChangeLog index daa6dc51b..4077121c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +* 18.2.0 +- Google Ads API v12 release. +- Bump proto-plus to 1.22.1. +- Remove example for Add Dynamic Page Feed. +- Remove example for Add Smart Display Ad. +- Remove example for Add Local Campaign. +- Remove usage of GenerateProductMixes in Forecast Reach example. +- Update example Create Experiment to rename ExperimentArm.trial to ExperimentArm.experiment. +- Update example Add Smart Campaign to support KeywordThemeSuggestion changes. + * 18.1.0 - Google Ads API v11_1 release. - Bump protobuf dependency to version 4.21.5. diff --git a/examples/account_management/approve_merchant_center_link.py b/examples/account_management/approve_merchant_center_link.py index 44cee978c..a99ee1e3d 100644 --- a/examples/account_management/approve_merchant_center_link.py +++ b/examples/account_management/approve_merchant_center_link.py @@ -125,7 +125,7 @@ def update_merchant_center_link_status( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Approves a Merchant Center link request.") diff --git a/examples/account_management/create_customer.py b/examples/account_management/create_customer.py index ee4880a93..390d1de7d 100755 --- a/examples/account_management/create_customer.py +++ b/examples/account_management/create_customer.py @@ -58,7 +58,7 @@ def main(client, manager_customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Creates a new client under the given manager.") diff --git a/examples/account_management/get_account_hierarchy.py b/examples/account_management/get_account_hierarchy.py index 4a68d46c1..6a76eea52 100755 --- a/examples/account_management/get_account_hierarchy.py +++ b/examples/account_management/get_account_hierarchy.py @@ -179,7 +179,7 @@ def print_account_hierarchy( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This example gets the account hierarchy of the specified " diff --git a/examples/account_management/get_account_information.py b/examples/account_management/get_account_information.py index 22d569922..958b0d612 100755 --- a/examples/account_management/get_account_information.py +++ b/examples/account_management/get_account_information.py @@ -55,7 +55,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/account_management/get_change_details.py b/examples/account_management/get_change_details.py index 6081f1ebf..29bf694c1 100755 --- a/examples/account_management/get_change_details.py +++ b/examples/account_management/get_change_details.py @@ -186,7 +186,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This example gets specific details about the most recent " diff --git a/examples/account_management/get_change_summary.py b/examples/account_management/get_change_summary.py index fd8868595..983d2089a 100755 --- a/examples/account_management/get_change_summary.py +++ b/examples/account_management/get_change_summary.py @@ -85,7 +85,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read a google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/account_management/get_pending_invitations.py b/examples/account_management/get_pending_invitations.py index 1a96e85db..6054ea68a 100755 --- a/examples/account_management/get_pending_invitations.py +++ b/examples/account_management/get_pending_invitations.py @@ -65,7 +65,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Retrieves pending invitations for a customer account.") diff --git a/examples/account_management/invite_user_with_access_role.py b/examples/account_management/invite_user_with_access_role.py index 3b99aaa10..81642f6a8 100755 --- a/examples/account_management/invite_user_with_access_role.py +++ b/examples/account_management/invite_user_with_access_role.py @@ -59,7 +59,7 @@ def main(client, customer_id, email_address, access_role): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/account_management/link_manager_to_client.py b/examples/account_management/link_manager_to_client.py index bcae1ab2b..5a5d2d5cd 100755 --- a/examples/account_management/link_manager_to_client.py +++ b/examples/account_management/link_manager_to_client.py @@ -85,8 +85,12 @@ def main(client, customer_id, manager_customer_id): ) manager_link_operation = client.get_type("CustomerManagerLinkOperation") manager_link = manager_link_operation.update - manager_link.resource_name = customer_manager_link_service.customer_manager_link_path( - customer_id, manager_customer_id, manager_link_id, + manager_link.resource_name = ( + customer_manager_link_service.customer_manager_link_path( + customer_id, + manager_customer_id, + manager_link_id, + ) ) manager_link.status = client.enums.ManagerLinkStatusEnum.ACTIVE @@ -108,7 +112,7 @@ def main(client, customer_id, manager_customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/account_management/list_accessible_customers.py b/examples/account_management/list_accessible_customers.py index 19120f43e..abba64ccb 100755 --- a/examples/account_management/list_accessible_customers.py +++ b/examples/account_management/list_accessible_customers.py @@ -44,7 +44,7 @@ def main(client): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") try: main(googleads_client) diff --git a/examples/account_management/reject_merchant_center_link.py b/examples/account_management/reject_merchant_center_link.py index 19b12d09b..581ddbf1f 100644 --- a/examples/account_management/reject_merchant_center_link.py +++ b/examples/account_management/reject_merchant_center_link.py @@ -131,7 +131,7 @@ def remove_merchant_center_link( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/account_management/update_user_access.py b/examples/account_management/update_user_access.py index 5bcc6f73e..1c9c975d2 100755 --- a/examples/account_management/update_user_access.py +++ b/examples/account_management/update_user_access.py @@ -137,7 +137,7 @@ def modify_user_access(client, customer_id, user_id, access_role): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This code example updates the access role of a user, " diff --git a/examples/advanced_operations/add_ad_customizer.py b/examples/advanced_operations/add_ad_customizer.py index 2c7445df0..297fff687 100755 --- a/examples/advanced_operations/add_ad_customizer.py +++ b/examples/advanced_operations/add_ad_customizer.py @@ -263,7 +263,7 @@ def create_ad_with_customizations( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( @@ -281,7 +281,11 @@ def create_ad_with_customizations( help="The Google Ads customer ID.", ) parser.add_argument( - "-a", "--ad_group_id", type=str, required=True, help="An ad group ID.", + "-a", + "--ad_group_id", + type=str, + required=True, + help="An ad group ID.", ) args = parser.parse_args() diff --git a/examples/advanced_operations/add_ad_group_bid_modifier.py b/examples/advanced_operations/add_ad_group_bid_modifier.py index 4d87546b6..5ec9a03ed 100755 --- a/examples/advanced_operations/add_ad_group_bid_modifier.py +++ b/examples/advanced_operations/add_ad_group_bid_modifier.py @@ -65,7 +65,7 @@ def main(client, customer_id, ad_group_id, bid_modifier_value): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/add_app_campaign.py b/examples/advanced_operations/add_app_campaign.py index 0733bd1ba..688a4f234 100755 --- a/examples/advanced_operations/add_app_campaign.py +++ b/examples/advanced_operations/add_app_campaign.py @@ -42,9 +42,7 @@ def main(client, customer_id): ) # Sets campaign targeting. - set_campaign_targeting_criteria( - client, customer_id, campaign_resource_name - ) + set_campaign_targeting_criteria(client, customer_id, campaign_resource_name) # Creates an Ad Group. ad_group_resource_name = create_ad_group( @@ -297,7 +295,7 @@ def create_ad_text_asset(client, text): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/add_bidding_data_exclusion.py b/examples/advanced_operations/add_bidding_data_exclusion.py index 1952142ad..724b3df86 100755 --- a/examples/advanced_operations/add_bidding_data_exclusion.py +++ b/examples/advanced_operations/add_bidding_data_exclusion.py @@ -80,7 +80,7 @@ def main(client, customer_id, start_date_time, end_date_time): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a data exclusion for conversions in Smart Bidding " diff --git a/examples/advanced_operations/add_bidding_seasonality_adjustment.py b/examples/advanced_operations/add_bidding_seasonality_adjustment.py index 1b6672e4a..5e74275a3 100755 --- a/examples/advanced_operations/add_bidding_seasonality_adjustment.py +++ b/examples/advanced_operations/add_bidding_seasonality_adjustment.py @@ -94,7 +94,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a seasonality adjustment for conversions in Smart " diff --git a/examples/advanced_operations/add_call_ad.py b/examples/advanced_operations/add_call_ad.py index 541f39988..eb548aa36 100755 --- a/examples/advanced_operations/add_call_ad.py +++ b/examples/advanced_operations/add_call_ad.py @@ -101,7 +101,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Adds a call extension to a specific account.") diff --git a/examples/advanced_operations/add_display_upload_ad.py b/examples/advanced_operations/add_display_upload_ad.py index 288fcb7dc..413a02c61 100644 --- a/examples/advanced_operations/add_display_upload_ad.py +++ b/examples/advanced_operations/add_display_upload_ad.py @@ -150,7 +150,7 @@ def create_display_upload_ad_group_ad( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a display upload ad to a given ad group." diff --git a/examples/advanced_operations/add_dynamic_page_feed_asset.py b/examples/advanced_operations/add_dynamic_page_feed_asset.py deleted file mode 100755 index a425560f6..000000000 --- a/examples/advanced_operations/add_dynamic_page_feed_asset.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env python -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example adds a page feed with URLs for a Dynamic Search Ads campaign.""" - - -import argparse -from datetime import datetime -import sys - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - - -def main(client, customer_id, campaign_id, ad_group_id): - """The main method that creates all necessary entities for the example. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID. - campaign_id: a campaign ID. - ad_group_id: an ad group ID. - """ - # The label for the DSA page URLs. - dsa_page_url_label = "discounts" - - # Creates a list of assets. - asset_resource_names = create_assets( - client, dsa_page_url_label, customer_id - ) - - # Creates an AssetSet - this is a collection of assets that can be - # associated with a campaign. Note: do not confuse this with an AssetGroup. - # An AssetGroup replaces AdGroups in some types of campaigns. - asset_set_resource_name = create_asset_set(client, customer_id) - - # Adds the Assets to the AssetSet. - add_assets_to_asset_set( - client, asset_resource_names, asset_set_resource_name, customer_id - ) - - # Links the AssetSet to the Campaign. - link_asset_set_to_campaign( - client, asset_set_resource_name, customer_id, campaign_id - ) - - # Optional: Targets web pages matching the feed's label in the ad group. - add_dsa_target(client, dsa_page_url_label, customer_id, ad_group_id) - - -# [START add_asset] -def create_assets(client, dsa_page_url_label, customer_id): - """Creates Assets to be used in a DSA page feed. - - Args: - client: an initialized GoogleAdsClient instance. - dsa_page_url_label: a label for the DSA page URLs. - customer_id: a client customer ID. - - Returns: - a list of asset resource names. - """ - urls = [ - "http://www.example.com/discounts/rental-cars", - "http://www.example.com/discounts/hotel-deals", - "http://www.example.com/discounts/flight-deals", - ] - - operations = [] - for url in urls: - operation = client.get_type("AssetOperation") - page_feed_asset = operation.create.page_feed_asset - page_feed_asset.page_url = url - page_feed_asset.labels.append(dsa_page_url_label) - operations.append(operation) - - asset_service = client.get_service("AssetService") - response = asset_service.mutate_assets( - customer_id=customer_id, operations=operations - ) - - resource_names = [] - for result in response.results: - resource_name = result.resource_name - print(f"Created asset with resource name '{resource_name}'") - resource_names.append(resource_name) - - return resource_names - # [END add_asset] - - -# [START add_asset_set] -def create_asset_set(client, customer_id): - """Creates an AssetSet. - - The AssetSet will be used to link the dynamic page feed assets to a - campaign. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID. - - Returns: - an asset set resource name. - """ - operation = client.get_type("AssetSetOperation") - asset_set = operation.create - asset_set.name = f"My dynamic page feed {datetime.now()}" - asset_set.type_ = client.enums.AssetSetTypeEnum.PAGE_FEED - - asset_set_service = client.get_service("AssetSetService") - response = asset_set_service.mutate_asset_sets( - customer_id=customer_id, operations=[operation] - ) - resource_name = response.results[0].resource_name - print(f"Created asset set with resource name '{resource_name}'") - - return resource_name - # [END add_asset_set] - - -# [START add_asset_set_asset] -def add_assets_to_asset_set( - client, asset_resource_names, asset_set_resource_name, customer_id -): - """Adds an Asset to an AssetSet by creating an AssetSetAsset link. - - Args: - client: an initialized GoogleAdsClient instance. - asset_resource_names: a list of asset resource names. - asset_set_resource_name: a resource name for an asset set. - customer_id: a client customer ID. - """ - operations = [] - for asset_resource_name in asset_resource_names: - operation = client.get_type("AssetSetAssetOperation") - asset_set_asset = operation.create - asset_set_asset.asset = asset_resource_name - asset_set_asset.asset_set = asset_set_resource_name - operations.append(operation) - - asset_set_asset_service = client.get_service("AssetSetAssetService") - response = asset_set_asset_service.mutate_asset_set_assets( - customer_id=customer_id, operations=operations - ) - resource_name = response.results[0].resource_name - print(f"Created asset set asset with resource name '{resource_name}'") - # [END add_asset_set_asset] - - -# [START add_campaign_asset_set] -def link_asset_set_to_campaign( - client, asset_set_resource_name, customer_id, campaign_id -): - """Links an AssetSet to a Campaign by creating a CampaignAssetSet. - - Args: - client: an initialized GoogleAdsClient instance. - asset_set_resource_name: a resource name for an asset set. - customer_id: a client customer ID. - campaign_id: a campaign ID. - """ - googleads_service = client.get_service("GoogleAdsService") - operation = client.get_type("CampaignAssetSetOperation") - campaign_asset_set = operation.create - campaign_asset_set.campaign = googleads_service.campaign_path( - customer_id, campaign_id - ) - campaign_asset_set.asset_set = asset_set_resource_name - - campaign_asset_set_service = client.get_service("CampaignAssetSetService") - response = campaign_asset_set_service.mutate_campaign_asset_sets( - customer_id=customer_id, operations=[operation] - ) - resource_name = response.results[0].resource_name - print(f"Created a campaign asset set with resource name '{resource_name}'") - # [END add_campaign_asset_set] - - -# [START add_dsa_target] -def add_dsa_target(client, dsa_page_url_label, customer_id, ad_group_id): - """Creates an ad group criterion targeting the DSA label. - - Args: - client: an initialized GoogleAdsClient instance. - dsa_page_url_label: a label for the DSA page URLs. - customer_id: a client customer ID. - ad_group_id: an ad group ID. - """ - googleads_service = client.get_service("GoogleAdsService") - operation = client.get_type("AdGroupCriterionOperation") - # Creates the ad group criterion. - ad_group_criterion = operation.create - ad_group_criterion.ad_group = googleads_service.ad_group_path( - customer_id, ad_group_id - ) - ad_group_criterion.cpc_bid_micros = 1500000 - - # Creates the webpage info, or criterion for targeting webpages of an - # advertiser's website. - webpage = ad_group_criterion.webpage - webpage.criterion_name = "Test Criterion" - # Creates the webpage condition info that targets an advertiser's webpages - # based on the custom label specified by the dsaPageUrlLabel - # (e.g. "discounts"). - webpage_condition = client.get_type("WebpageConditionInfo") - webpage_condition.operand = ( - client.enums.WebpageConditionOperandEnum.CUSTOM_LABEL - ) - webpage_condition.argument = dsa_page_url_label - webpage.conditions.append(webpage_condition) - - ad_group_criterion_service = client.get_service("AdGroupCriterionService") - response = ad_group_criterion_service.mutate_ad_group_criteria( - customer_id=customer_id, operations=[operation] - ) - resource_name = response.results[0].resource_name - print(f"Created ad group criterion with resource name '{resource_name}'") - # [END add_dsa_target] - - -if __name__ == "__main__": - # GoogleAdsClient will read the google-ads.yaml configuration file in the - # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - - parser = argparse.ArgumentParser( - description=( - "Adds a page feed with URLs for a Dynamic Search Ads Campaign." - ) - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - parser.add_argument( - "-i", "--campaign_id", type=str, required=True, help="The campaign ID." - ) - parser.add_argument( - "-a", "--ad_group_id", type=str, required=True, help="The ad group ID." - ) - args = parser.parse_args() - - try: - main( - googleads_client, - args.customer_id, - args.campaign_id, - args.ad_group_id, - ) - except GoogleAdsException as ex: - print( - f'Request with ID "{ex.request_id}" failed with status ' - f'"{ex.error.code().name}" and includes the following errors:' - ) - for error in ex.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) diff --git a/examples/advanced_operations/add_dynamic_search_ads.py b/examples/advanced_operations/add_dynamic_search_ads.py index fc04c9f82..eb91aa2ef 100755 --- a/examples/advanced_operations/add_dynamic_search_ads.py +++ b/examples/advanced_operations/add_dynamic_search_ads.py @@ -260,7 +260,7 @@ def add_webpage_criterion(client, customer_id, ad_group_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/add_local_campaign.py b/examples/advanced_operations/add_local_campaign.py deleted file mode 100755 index b5e231dce..000000000 --- a/examples/advanced_operations/add_local_campaign.py +++ /dev/null @@ -1,364 +0,0 @@ -#!/usr/bin/env python -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example adds a Local campaign. - -Prerequisite: To create a Local campaign, you need to define the store locations -you want to promote by linking your Business Profile account or selecting -affiliate locations. More information about Local campaigns can be found at: -https://support.google.com/google-ads/answer/9118422. -""" - - -import argparse -import requests -import sys -from uuid import uuid4 - - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - - -_MARKETING_IMAGE_URL = "https://gaagl.page.link/Eit5" -_LOGO_IMAGE_URL = "https://gaagl.page.link/bjYi" -_YOUTUBE_VIDEO_ID = "ECpDzH9gXh8" - - -def main(client, customer_id): - """The main method that creates all necessary entities for the example. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - """ - budget_resource_name = create_campaign_budget(client, customer_id) - campaign_resource_name = create_campaign( - client, customer_id, budget_resource_name - ) - ad_group_resource_name = create_ad_group( - client, customer_id, campaign_resource_name - ) - create_local_ad(client, customer_id, ad_group_resource_name) - - -# [START add_local_campaign] -def create_campaign_budget(client, customer_id): - """Adds a campaign budget to the given client account. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - - Returns: - A str of the resource name for the newly created campaign budget. - """ - # Create a CampaignBudgetOperation. - campaign_budget_operation = client.get_type("CampaignBudgetOperation") - campaign_budget = campaign_budget_operation.create - campaign_budget.name = f"Interplanetary Cruise Budget #{uuid4()}" - campaign_budget.amount_micros = 50000000 - campaign_budget.delivery_method = ( - client.enums.BudgetDeliveryMethodEnum.STANDARD - ) - # A Local campaign cannot use a shared campaign budget. - campaign_budget.explicitly_shared = False - - # Issue a mutate request to add the campaign budget. - campaign_budget_service = client.get_service("CampaignBudgetService") - response = campaign_budget_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[campaign_budget_operation] - ) - resource_name = response.results[0].resource_name - print(f"Created campaign budget with resource name: '{resource_name}'") - return resource_name - # [END add_local_campaign] - - -# [START add_local_campaign_1] -def create_campaign(client, customer_id, budget_resource_name): - """Adds a Local campaign to the given client account using the given budget. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - budget_resource_name: the resource name str for a campaign budget. - - Returns: - A str of the resource name for the newly created campaign. - """ - # Create a CampaignOperation. - campaign_operation = client.get_type("CampaignOperation") - # Create a Campaign. - campaign = campaign_operation.create - campaign.name = f"Interplanetary Cruise Local #{uuid4()}" - campaign.campaign_budget = budget_resource_name - # Recommendation: Set the campaign to PAUSED when creating it to prevent - # the ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - # All Local campaigns have an advertising_channel_type of LOCAL and - # advertising_channel_sub_type of LOCAL_CAMPAIGN. - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.LOCAL - ) - campaign.advertising_channel_sub_type = ( - client.enums.AdvertisingChannelSubTypeEnum.LOCAL_CAMPAIGN - ) - # Bidding strategy must be set directly on the campaign. - # Setting a portfolio bidding strategy by resource name is not supported. - # Maximize conversion value is the only strategy supported for Local - # campaigns. An optional ROAS (Return on Advertising Spend) can be set for - # maximize_conversion_value. The ROAS value must be specified as a ratio in - # the API. It is calculated by dividing "total value" by "total spend". - # For more information on maximize conversion value, see the support - # article: http://support.google.com/google-ads/answer/7684216. - # A target_roas of 3.5 corresponds to a 350% return on ad spend. - campaign.maximize_conversion_value.target_roas = 3.5 - # Configure the Local campaign setting. Use the locations associated with - # the customer's linked Business Profile account. - campaign.local_campaign_setting.location_source_type = ( - client.enums.LocationSourceTypeEnum.GOOGLE_MY_BUSINESS - ) - # Optimization goal setting is mandatory for Local campaigns. This example - # selects driving directions and call clicks as goals. - optimization_goal_type_enum = client.enums.OptimizationGoalTypeEnum - campaign.optimization_goal_setting.optimization_goal_types.extend( - [ - optimization_goal_type_enum.CALL_CLICKS, - optimization_goal_type_enum.DRIVING_DIRECTIONS, - ] - ) - - campaign_service = client.get_service("CampaignService") - response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[campaign_operation] - ) - resource_name = response.results[0].resource_name - print(f"Created Local Campaign with resource name: '{resource_name}'") - return resource_name - # [END add_local_campaign_1] - - -# [START add_local_campaign_2] -def create_ad_group(client, customer_id, campaign_resource_name): - """Adds an ad group to the given client account under the given campaign. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - campaign_resource_name: the resource name str for a campaign. - - Returns: - A str of the resource name for the newly created ad group. - """ - ad_group_operation = client.get_type("AdGroupOperation") - ad_group = ad_group_operation.create - # Note that the ad group type must not be set. - # Since the advertising_channel_subType is LOCAL_CAMPAIGN: - # 1. you cannot override bid settings at the ad group level. - # 2. you cannot add ad group criteria. - ad_group.name = f"Earth to Mars Cruises #{uuid4()}" - ad_group.status = client.enums.AdGroupStatusEnum.ENABLED - ad_group.campaign = campaign_resource_name - - ad_group_service = client.get_service("AdGroupService") - response = ad_group_service.mutate_ad_groups( - customer_id=customer_id, operations=[ad_group_operation] - ) - resource_name = response.results[0].resource_name - print(f"Created AdGroup with resource name: '{resource_name}'") - return resource_name - # [END add_local_campaign_2] - - -# [START add_local_campaign_3] -def create_local_ad(client, customer_id, ad_group_resource_name): - """Adds a local ad to the given client account under the given ad group. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - ad_group_resource_name: the resource name str for a ad group. - """ - ad_group_ad_operation = client.get_type("AdGroupAdOperation") - ad_group_ad = ad_group_ad_operation.create - ad_group_ad.ad_group = ad_group_resource_name - ad_group_ad.status = client.enums.AdGroupAdStatusEnum.ENABLED - ad_group_ad.ad.final_urls.append("https://www.example.com") - ad_group_ad.ad.local_ad.headlines.extend( - [ - create_ad_text_asset(client, "Best Space Cruise Line"), - create_ad_text_asset(client, "Experience the Stars"), - ] - ) - ad_group_ad.ad.local_ad.descriptions.extend( - [ - create_ad_text_asset(client, "Buy your tickets now"), - create_ad_text_asset(client, "Visit the Red Planet"), - ] - ) - ad_group_ad.ad.local_ad.call_to_actions.append( - create_ad_text_asset(client, "Shop Now") - ) - marketing_image = client.get_type("AdImageAsset") - marketing_image.asset = create_image_asset( - client, customer_id, _MARKETING_IMAGE_URL, "Marketing Image" - ) - ad_group_ad.ad.local_ad.marketing_images.append(marketing_image) - - logo_image = client.get_type("AdImageAsset") - logo_image.asset = create_image_asset( - client, customer_id, _LOGO_IMAGE_URL, "Square Marketing Image" - ) - ad_group_ad.ad.local_ad.logo_images.append(logo_image) - - video = client.get_type("AdVideoAsset") - video.asset = create_youtube_video_asset( - client, customer_id, _YOUTUBE_VIDEO_ID, "Local Campaigns" - ) - ad_group_ad.ad.local_ad.videos.append(video) - - ad_group_ad_service = client.get_service("AdGroupAdService") - response = ad_group_ad_service.mutate_ad_group_ads( - customer_id=customer_id, operations=[ad_group_ad_operation] - ) - resource_name = response.results[0].resource_name - print(f"Created ad group ad with resource name: '{resource_name}'") - - -def create_ad_text_asset(client, text): - """Creates an ad text asset with the given text value. - - Args: - client: an initialized GoogleAdsClient instance. - text: a str for the text value of the ad text asset. - - Returns: - an ad text asset. - """ - ad_text_asset = client.get_type("AdTextAsset") - ad_text_asset.text = text - return ad_text_asset - # [END add_local_campaign_3] - - -# [START add_local_campaign_4] -def create_image_asset(client, customer_id, image_url, image_name): - """Creates an asset with the given image URL and name. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - image_url: a str URL to download an image. - image_name: a str to use to name the image. - - Returns: - an asset. - """ - asset_operation = client.get_type("AssetOperation") - asset = asset_operation.create - asset.name = image_name - asset.type_ = client.enums.AssetTypeEnum.IMAGE - asset.image_asset.data = get_image_bytes(image_url) - asset_service = client.get_service("AssetService") - response = asset_service.mutate_assets( - customer_id=customer_id, operations=[asset_operation] - ) - resource_name = response.results[0].resource_name - print( - "A new image asset has been added with resource name: " - f"'{resource_name}'" - ) - return resource_name - - -def get_image_bytes(url): - """Loads image data from a URL. - - Args: - url: a URL str. - - Returns: - Images bytes loaded from the given URL. - """ - response = requests.get(url) - return response.content - # [END add_local_campaign_4] - - -# [START add_local_campaign_5] -def create_youtube_video_asset( - client, customer_id, youtube_video_id, youtube_video_name -): - """Creates a asset with the given YouTube video ID and name. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID str. - youtube_video_id: a str of a YouTube video ID. - youtube_video_name: a str to use for the name of the video asset. - - Returns: - an Asset. - """ - asset_operation = client.get_type("AssetOperation") - asset = asset_operation.create - asset.name = youtube_video_name - asset.type_ = client.enums.AssetTypeEnum.YOUTUBE_VIDEO - asset.youtube_video_asset.youtube_video_id = youtube_video_id - - asset_service = client.get_service("AssetService") - response = asset_service.mutate_assets( - customer_id=customer_id, operations=[asset_operation] - ) - resource_name = response.results[0].resource_name - print( - "A new YouTube video asset has been added with resource name: " - f"'{resource_name}'" - ) - return resource_name - # [END add_local_campaign_5] - - -if __name__ == "__main__": - # GoogleAdsClient will read the google-ads.yaml configuration file in the - # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - - parser = argparse.ArgumentParser( - description="Adds a Local Campaign to the given account." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - try: - main(googleads_client, args.customer_id) - except GoogleAdsException as ex: - print( - f'Request with ID "{ex.request_id}" failed with status ' - f'"{ex.error.code().name}" and includes the following errors:' - ) - for error in ex.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) diff --git a/examples/advanced_operations/add_performance_max_campaign.py b/examples/advanced_operations/add_performance_max_campaign.py index 563adb4eb..c0a4ea393 100644 --- a/examples/advanced_operations/add_performance_max_campaign.py +++ b/examples/advanced_operations/add_performance_max_campaign.py @@ -670,7 +670,7 @@ def create_asset_group_signal_operation(client, customer_id, audience_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Creates a Performance Max campaign.") diff --git a/examples/advanced_operations/add_responsive_search_ad_with_ad_customizer.py b/examples/advanced_operations/add_responsive_search_ad_with_ad_customizer.py index 420a09a56..76f07e2cc 100755 --- a/examples/advanced_operations/add_responsive_search_ad_with_ad_customizer.py +++ b/examples/advanced_operations/add_responsive_search_ad_with_ad_customizer.py @@ -63,9 +63,7 @@ def main(client, customer_id, ad_group_id, customizer_attribute_name): # [START add_responsive_search_ad_with_ad_customizer_1] -def create_customizer_attribute( - client, customer_id, customizer_attribute_name -): +def create_customizer_attribute(client, customer_id, customizer_attribute_name): """Creates a customizer attribute with the given customizer attribute name. Args: @@ -212,7 +210,7 @@ def create_responsive_search_ad_with_customization( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/add_smart_campaign.py b/examples/advanced_operations/add_smart_campaign.py index 5fd6da0ce..7a5cc32cd 100755 --- a/examples/advanced_operations/add_smart_campaign.py +++ b/examples/advanced_operations/add_smart_campaign.py @@ -19,7 +19,6 @@ """ import argparse -import ctypes import sys from uuid import uuid4 @@ -51,7 +50,7 @@ def main( client, customer_id, keyword_text, - freeform_keyword_text, + free_form_keyword_text, business_profile_location, business_name, ): @@ -61,7 +60,7 @@ def main( client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. keyword_text: a keyword used for generating keyword themes. - freeform_keyword_text: a keyword used to create a free-form keyword + free_form_keyword_text: a keyword used to create a free-form keyword theme. business_profile_location: the ID of a Business Profile location. business_name: the name of a Business Profile. @@ -79,28 +78,31 @@ def main( # generate a list of keyword themes using the SuggestKeywordThemes method # on the SmartCampaignSuggestService. It is strongly recommended that you # use this strategy for generating keyword themes. - keyword_theme_constants = get_keyword_theme_suggestions( + keyword_themes = get_keyword_theme_suggestions( client, customer_id, suggestion_info ) - # If a keyword text is given retrieve keyword theme constant suggestions - # from the KeywordThemeConstantService and append them to the existing list. + # If a keyword text is given, retrieve keyword theme constant suggestions + # from the KeywordThemeConstantService, map them to KeywordThemes, and + # append them to the existing list. This logic should ideally only be used + # if the suggestions from the get_keyword_theme_suggestions function are + # insufficient. if keyword_text: - keyword_theme_constants.extend( + keyword_themes.extend( get_keyword_text_auto_completions(client, keyword_text) ) - # Map the KeywordThemeConstants retrieved by the previous two steps to + # Map the KeywordThemes retrieved by the previous two steps to # KeywordThemeInfo instances. - keyword_theme_infos = map_keyword_theme_constants_to_infos( - client, keyword_theme_constants + keyword_theme_infos = map_keyword_themes_to_keyword_infos( + client, keyword_themes ) # If a free-form keyword text is given we create a KeywordThemeInfo instance # from it and add it to the existing list. - if freeform_keyword_text: + if free_form_keyword_text: keyword_theme_infos.append( - get_freeform_keyword_theme_info(client, freeform_keyword_text) + get_free_form_keyword_theme_info(client, free_form_keyword_text) ) # Now add the generated keyword themes to the suggestion info instance. @@ -167,7 +169,7 @@ def main( # [START add_smart_campaign_11] def get_keyword_theme_suggestions(client, customer_id, suggestion_info): - """Retrieves KeywordThemeConstants using the given suggestion info. + """Retrieves KeywordThemes using the given suggestion info. Here we use the SuggestKeywordThemes method, which uses all of the business details included in the given SmartCampaignSuggestionInfo instance to @@ -182,7 +184,7 @@ def get_keyword_theme_suggestions(client, customer_id, suggestion_info): about the business being advertised. Returns: - a list of KeywordThemeConstants. + a list of KeywordThemes. """ smart_campaign_suggest_service = client.get_service( "SmartCampaignSuggestService" @@ -196,8 +198,8 @@ def get_keyword_theme_suggestions(client, customer_id, suggestion_info): ) print( - f"Retrieved {len(response.keyword_themes)} keyword theme constant " - "suggestions from the SuggestKeywordThemes method." + f"Retrieved {len(response.keyword_themes)} keyword theme suggestions " + "from the SuggestKeywordThemes method." ) return response.keyword_themes # [END add_smart_campaign_11] @@ -208,14 +210,14 @@ def get_keyword_text_auto_completions(client, keyword_text): """Retrieves KeywordThemeConstants for the given keyword text. These KeywordThemeConstants are derived from autocomplete data for the - given keyword text. + given keyword text. They are mapped to KeywordThemes before being returned. Args: client: an initialized GoogleAdsClient instance. keyword_text: a keyword used for generating keyword themes. Returns: - a list of KeywordThemeConstants. + a list of KeywordThemes. """ keyword_theme_constant_service = client.get_service( "KeywordThemeConstantService" @@ -233,43 +235,65 @@ def get_keyword_text_auto_completions(client, keyword_text): f"Retrieved {len(response.keyword_theme_constants)} keyword theme " f"constants using the keyword: '{keyword_text}'" ) - return response.keyword_theme_constants + + # Map the keyword theme constants to KeywordTheme instances for consistency + # with the response from SmartCampaignSuggestService.SuggestKeywordThemes. + keyword_themes = [] + KeywordTheme = client.get_type("SuggestKeywordThemesResponse").KeywordTheme + for keyword_theme_constant in response.keyword_theme_constants: + keyword_theme = KeywordTheme() + keyword_theme.keyword_theme_constant = keyword_theme_constant + keyword_themes.append(keyword_theme) + + return keyword_themes # [END add_smart_campaign] # [START add_smart_campaign_13] -def get_freeform_keyword_theme_info(client, freeform_keyword_text): +def get_free_form_keyword_theme_info(client, free_form_keyword_text): """Creates a KeywordThemeInfo using the given free-form keyword text. Args: client: an initialized GoogleAdsClient instance. - freeform_keyword_text: a keyword used to create a free-form keyword + free_form_keyword_text: a keyword used to create a free-form keyword theme. Returns: a KeywordThemeInfo instance. """ info = client.get_type("KeywordThemeInfo") - info.free_form_keyword_theme = freeform_keyword_text + info.free_form_keyword_theme = free_form_keyword_text return info # [END add_smart_campaign_13] -def map_keyword_theme_constants_to_infos(client, keyword_theme_constants): - """Maps a list of KeywordThemeConstants to KeywordThemeInfos. +def map_keyword_themes_to_keyword_infos(client, keyword_themes): + """Maps a list of KeywordThemes to KeywordThemeInfos. Args: client: an initialized GoogleAdsClient instance. - keyword_theme_constants: a list of KeywordThemeConstants. + keyword_themes: a list of KeywordThemes. Returns: a list of KeywordThemeInfos. """ infos = [] - for constant in keyword_theme_constants: + for keyword_theme in keyword_themes: info = client.get_type("KeywordThemeInfo") - info.keyword_theme_constant = constant.resource_name - infos.append(info) + # Check if the keyword_theme_constant field is set. + if "keyword_theme_constant" in keyword_theme: + info.keyword_theme_constant = ( + keyword_theme.keyword_theme_constant.resource_name + ) + infos.append(info) + # Check if the free_form_keyword_theme field is set. + elif "free_form_keyword_theme" in keyword_theme: + info.free_form_keyword_theme = keyword_theme.free_form_keyword_theme + infos.append(info) + else: + raise ValueError( + f"A malformed KeywordTheme was encountered: {keyword_theme}" + ) return infos @@ -548,7 +572,8 @@ def create_smart_campaign_setting_operation( Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. - business_profile_location: the resource name of a Business Profile location. + business_profile_location: the resource name of a Business Profile + location. business_name: the name of a Business Profile. Returns: @@ -786,7 +811,7 @@ def print_response_details(response): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser(description=("Creates a Smart campaign.")) # The following argument(s) should be provided to run the example. @@ -812,7 +837,7 @@ def print_response_details(response): ) parser.add_argument( "-f", - "--freeform_keyword_text", + "--free_form_keyword_text", type=str, required=False, help=( @@ -854,7 +879,7 @@ def print_response_details(response): googleads_client, args.customer_id, args.keyword_text, - args.freeform_keyword_text, + args.free_form_keyword_text, args.business_profile_location, args.business_name, ) diff --git a/examples/advanced_operations/add_smart_display_ad.py b/examples/advanced_operations/add_smart_display_ad.py deleted file mode 100755 index 057eb81d7..000000000 --- a/examples/advanced_operations/add_smart_display_ad.py +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env python -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This adds a smart display campaign, an ad group, and a responsive display ad. - -More information about Smart Display campaigns can be found at: -https://support.google.com/google-ads/answer/7020281 - -IMPORTANT: The AssetService requires you to reuse what you've uploaded -previously. Therefore, you cannot create an image asset with the exactly same -bytes. In case you want to run this example more than once, note down the -created assets' resource names and specify them as command-line arguments for -marketing and square marketing images. - -Alternatively, you can modify the image URLs' constants directly to use other -images. You can find image specifications in the pydoc for -ResponsiveDisplayAdInfo in common/ad_type_infos_pb2.py. -""" - - -import argparse -import datetime -import requests -import sys -from uuid import uuid4 - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - - -_DATE_FORMAT = "%Y%m%d" -_MARKETING_IMAGE_URL = "https://gaagl.page.link/Eit5" -_MARKETING_IMAGE_WIDTH = 600 -_MARKETING_IMAGE_HEIGHT = 315 -_SQUARE_MARKETING_IMAGE_URL = "https://gaagl.page.link/bjYi" -_SQUARE_MARKETING_IMAGE_SIZE = 512 - - -def main( - client, - customer_id, - marketing_image_asset_id=None, - square_marketing_image_asset_id=None, -): - budget_resource_name = create_budget(client, customer_id) - print(f'Created budget with resource name "{budget_resource_name}".') - - campaign_resource_name = create_smart_display_campaign( - client, customer_id, budget_resource_name - ) - print( - "Created smart display campaign with resource name " - f'"{campaign_resource_name}".' - ) - - ad_group_resource_name = create_ad_group( - client, customer_id, campaign_resource_name - ) - print(f'Created ad group with resource name "{ad_group_resource_name}"') - - if marketing_image_asset_id: - print( - "Using existing marketing image asset with ID " - f'"{marketing_image_asset_id}".' - ) - else: - marketing_image_asset_id = upload_image_asset( - client, - customer_id, - _MARKETING_IMAGE_URL, - _MARKETING_IMAGE_WIDTH, - _MARKETING_IMAGE_HEIGHT, - "Marketing Image", - ) - print( - "Created marketing image asset with ID " - f'"{marketing_image_asset_id}".' - ) - - if square_marketing_image_asset_id: - print( - "Using existing square marketing image asset with ID " - f'"{square_marketing_image_asset_id}".' - ) - else: - square_marketing_image_asset_id = upload_image_asset( - client, - customer_id, - _SQUARE_MARKETING_IMAGE_URL, - _SQUARE_MARKETING_IMAGE_SIZE, - _SQUARE_MARKETING_IMAGE_SIZE, - "Square Marketing Image", - ) - print( - "Created square marketing image asset with ID " - f'"{square_marketing_image_asset_id}".' - ) - - responsive_display_ad_resource_name = create_responsive_display_ad( - client, - customer_id, - ad_group_resource_name, - marketing_image_asset_id, - square_marketing_image_asset_id, - ) - print( - "Created responsive display ad with resource name " - f'"{responsive_display_ad_resource_name}".' - ) - - print( - "Created responsive display ad with resource name " - f'"{responsive_display_ad_resource_name}".' - ) - - -# [START add_smart_display_ad] -def create_budget(client, customer_id): - campaign_budget_operation = client.get_type("CampaignBudgetOperation") - campaign_budget = campaign_budget_operation.create - campaign_budget.name = f"Interplanetary Cruise Budget #{uuid4()}" - campaign_budget.delivery_method = ( - client.enums.BudgetDeliveryMethodEnum.STANDARD - ) - campaign_budget.amount_micros = 500000 - - campaign_budget_service = client.get_service("CampaignBudgetService") - - try: - campaign_budget_response = ( - campaign_budget_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[campaign_budget_operation] - ) - ) - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - return campaign_budget_response.results[0].resource_name - # [END add_smart_display_ad] - - -# [START add_smart_display_ad_1] -def create_smart_display_campaign(client, customer_id, budget_resource_name): - campaign_service = client.get_service("CampaignService") - campaign_operation = client.get_type("CampaignOperation") - campaign = campaign_operation.create - campaign.name = f"Smart Display Campaign #{uuid4()}" - advertising_channel_type_enum = client.enums.AdvertisingChannelTypeEnum - campaign.advertising_channel_type = advertising_channel_type_enum.DISPLAY - advertising_channel_sub_type_enum = ( - client.enums.AdvertisingChannelSubTypeEnum - ) - # Smart Display campaign requires the advertising_channel_sub_type as - # "DISPLAY_SMART_CAMPAIGN". - campaign.advertising_channel_sub_type = ( - advertising_channel_sub_type_enum.DISPLAY_SMART_CAMPAIGN - ) - campaign_status_enum = client.enums.CampaignStatusEnum - campaign.status = campaign_status_enum.PAUSED - # Smart Display campaign requires the TargetCpa bidding strategy. - campaign.target_cpa.target_cpa_micros = 5000000 - campaign.campaign_budget = budget_resource_name - # Optional: Set the start and end date. - start_date = datetime.date.today() + datetime.timedelta(days=1) - campaign.start_date = start_date.strftime(_DATE_FORMAT) - end_date = start_date + datetime.timedelta(days=365) - campaign.end_date = end_date.strftime(_DATE_FORMAT) - - try: - campaign_response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[campaign_operation] - ) - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - return campaign_response.results[0].resource_name - # [END add_smart_display_ad_1] - - -# [START add_smart_display_ad_4] -def create_ad_group(client, customer_id, campaign_resource_name): - ad_group_service = client.get_service("AdGroupService") - ad_group_operation = client.get_type("AdGroupOperation") - ad_group = ad_group_operation.create - ad_group.name = f"Earth to Mars Cruises #{uuid4()}" - ad_group_status_enum = client.enums.AdGroupStatusEnum - ad_group.status = ad_group_status_enum.PAUSED - ad_group.campaign = campaign_resource_name - - try: - ad_group_response = ad_group_service.mutate_ad_groups( - customer_id=customer_id, operations=[ad_group_operation] - ) - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - return ad_group_response.results[0].resource_name - # [END add_smart_display_ad_4] - - -# [START add_smart_display_ad_3] -def upload_image_asset( - client, customer_id, image_url, image_width, image_height, image_name -): - # Download image from URL - image_content = requests.get(image_url).content - - asset_operation = client.get_type("AssetOperation") - asset = asset_operation.create - # Optional: Provide a unique friendly name to identify your asset. If you - # specify the name field, then both the asset name and the image being - # uploaded should be unique, and should not match another ACTIVE asset in - # this customer account. - # asset.name = f'Jupiter Trip #{uuid4()}' - asset_type_enum = client.enums.AssetTypeEnum - asset.type_ = asset_type_enum.IMAGE - asset.name = image_name - image_asset = asset.image_asset - image_asset.data = image_content - image_asset.file_size = len(image_content) - image_asset.mime_type = client.enums.MimeTypeEnum.IMAGE_JPEG - image_asset.full_size.width_pixels = image_width - image_asset.full_size.height_pixels = image_height - image_asset.full_size.url = image_url - - asset_service = client.get_service("AssetService") - content_type_enum = client.enums.ResponseContentTypeEnum - - request = client.get_type("MutateAssetsRequest") - request.customer_id = customer_id - request.operations = [asset_operation] - # Setting this parameter tells the API to return the Asset object in the - # response, allowing us to easily retrieve its ID. - request.response_content_type = content_type_enum.MUTABLE_RESOURCE - - try: - mutate_asset_response = asset_service.mutate_assets(request=request) - return mutate_asset_response.results[0].asset.id - except GoogleAdsException as ex: - handle_googleads_exception(ex) - # [END add_smart_display_ad_3] - - -# [START add_smart_display_ad_2] -def create_responsive_display_ad( - client, - customer_id, - ad_group_resource_name, - marketing_image_asset_id, - square_marketing_image_asset_id, -): - ad_group_ad_service = client.get_service("AdGroupAdService") - ad_group_ad_operation = client.get_type("AdGroupAdOperation") - ad_group_ad = ad_group_ad_operation.create - ad_group_ad.ad_group = ad_group_resource_name - ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED - ad = ad_group_ad.ad - ad.final_urls.append("https://www.example.com") - responsive_display_ad = ad.responsive_display_ad - - # Add a headline - headline = client.get_type("AdTextAsset") - headline.text = "Travel" - responsive_display_ad.headlines.append(headline) - - # Add the long headline - responsive_display_ad.long_headline.text = "Travel the World" - - # Add a description - description = client.get_type("AdTextAsset") - description.text = "Take to the air!" - responsive_display_ad.descriptions.append(description) - - # Add the business name - responsive_display_ad.business_name = "Google" - - asset_service = client.get_service("AssetService") - # Add a marketing image - marketing_image = client.get_type("AdImageAsset") - marketing_image.asset = asset_service.asset_path( - customer_id, marketing_image_asset_id - ) - responsive_display_ad.marketing_images.append(marketing_image) - - # Add a square marketing image - square_marketing_image = client.get_type("AdImageAsset") - square_marketing_image.asset = asset_service.asset_path( - customer_id, square_marketing_image_asset_id - ) - responsive_display_ad.square_marketing_images.append(square_marketing_image) - - # Add the call to action - responsive_display_ad.call_to_action_text = "Shop Now" - - # Add the price prefix - responsive_display_ad.price_prefix = "as low as" - - # Add the promo text - responsive_display_ad.promo_text = "Free shipping!" - - try: - ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads( - customer_id=customer_id, operations=[ad_group_ad_operation] - ) - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - return ad_group_ad_response.results[0].resource_name - # [END add_smart_display_ad_2] - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # GoogleAdsClient will read the google-ads.yaml configuration file in the - # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - - parser = argparse.ArgumentParser( - description=( - "Creates a Smart Display campaign, and an ad group that " - "are then used to create a responsive display ad." - ) - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - parser.add_argument( - "-m", - "--marketing_image_asset_id", - type=str, - required=False, - help=("The ID for an image asset to be used as a marketing image."), - ) - parser.add_argument( - "-s", - "--square_marketing_image_asset_id", - type=str, - required=False, - help=( - "The resource name for an image asset to be used as a square " - "marketing image." - ), - ) - args = parser.parse_args() - - main( - googleads_client, - args.customer_id, - args.marketing_image_asset_id, - args.square_marketing_image_asset_id, - ) diff --git a/examples/advanced_operations/create_and_attach_shared_keyword_set.py b/examples/advanced_operations/create_and_attach_shared_keyword_set.py index 270ac31a8..632080899 100755 --- a/examples/advanced_operations/create_and_attach_shared_keyword_set.py +++ b/examples/advanced_operations/create_and_attach_shared_keyword_set.py @@ -111,7 +111,7 @@ def handle_googleads_exception(exception): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py b/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py index 000df09a0..763cabb0f 100755 --- a/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py +++ b/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py @@ -135,7 +135,7 @@ def handle_googleads_exception(exception): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/advanced_operations/get_ad_group_bid_modifiers.py b/examples/advanced_operations/get_ad_group_bid_modifiers.py index 42fac9278..d477c75b8 100755 --- a/examples/advanced_operations/get_ad_group_bid_modifiers.py +++ b/examples/advanced_operations/get_ad_group_bid_modifiers.py @@ -99,7 +99,7 @@ def main(client, customer_id, page_size, ad_group_id=None): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List ad group bid modifiers for specified customer." diff --git a/examples/advanced_operations/use_cross_account_bidding_strategy.py b/examples/advanced_operations/use_cross_account_bidding_strategy.py index 78ac9b56f..0c62c93fb 100755 --- a/examples/advanced_operations/use_cross_account_bidding_strategy.py +++ b/examples/advanced_operations/use_cross_account_bidding_strategy.py @@ -219,7 +219,7 @@ def attach_cross_account_bidding_strategy_to_campaign( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser(description=("Creates a Smart campaign.")) # The following argument(s) should be provided to run the example. diff --git a/examples/advanced_operations/use_portfolio_bidding_strategy.py b/examples/advanced_operations/use_portfolio_bidding_strategy.py index 56f69d11d..9ba3f4790 100755 --- a/examples/advanced_operations/use_portfolio_bidding_strategy.py +++ b/examples/advanced_operations/use_portfolio_bidding_strategy.py @@ -125,7 +125,7 @@ def handle_googleads_exception(exception): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a campaign for specified customer." diff --git a/examples/basic_operations/add_ad_groups.py b/examples/basic_operations/add_ad_groups.py index 7075b6b08..e5e4ea562 100755 --- a/examples/basic_operations/add_ad_groups.py +++ b/examples/basic_operations/add_ad_groups.py @@ -49,7 +49,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds an ad group for specified customer and campaign id." diff --git a/examples/basic_operations/add_campaigns.py b/examples/basic_operations/add_campaigns.py index 2365da8a5..5602c12d0 100755 --- a/examples/basic_operations/add_campaigns.py +++ b/examples/basic_operations/add_campaigns.py @@ -116,7 +116,7 @@ def handle_googleads_exception(exception): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a campaign for specified customer." diff --git a/examples/basic_operations/add_keywords.py b/examples/basic_operations/add_keywords.py index e7b15cc48..d088772d4 100755 --- a/examples/basic_operations/add_keywords.py +++ b/examples/basic_operations/add_keywords.py @@ -64,7 +64,7 @@ def main(client, customer_id, ad_group_id, keyword_text): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/basic_operations/add_responsive_search_ad.py b/examples/basic_operations/add_responsive_search_ad.py index c99b8b87a..1a6464225 100755 --- a/examples/basic_operations/add_responsive_search_ad.py +++ b/examples/basic_operations/add_responsive_search_ad.py @@ -89,7 +89,7 @@ def create_ad_text_asset(client, text, pinned_field=None): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/basic_operations/get_ad_groups.py b/examples/basic_operations/get_ad_groups.py index 14b43e1e8..2802c9e48 100755 --- a/examples/basic_operations/get_ad_groups.py +++ b/examples/basic_operations/get_ad_groups.py @@ -55,7 +55,7 @@ def main(client, customer_id, page_size, campaign_id=None): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List ad groups for specified customer." diff --git a/examples/basic_operations/get_campaigns.py b/examples/basic_operations/get_campaigns.py index 6d4c7f233..04a7ca729 100755 --- a/examples/basic_operations/get_campaigns.py +++ b/examples/basic_operations/get_campaigns.py @@ -49,7 +49,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists all campaigns for specified customer." diff --git a/examples/basic_operations/get_expanded_text_ads.py b/examples/basic_operations/get_expanded_text_ads.py index abc6bcfc7..0ddf8c162 100755 --- a/examples/basic_operations/get_expanded_text_ads.py +++ b/examples/basic_operations/get_expanded_text_ads.py @@ -59,7 +59,7 @@ def main(client, customer_id, ad_group_id=None): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List ad groups for specified customer." diff --git a/examples/basic_operations/get_keywords.py b/examples/basic_operations/get_keywords.py index 7657ee9d8..6d1e7d61b 100755 --- a/examples/basic_operations/get_keywords.py +++ b/examples/basic_operations/get_keywords.py @@ -90,7 +90,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/basic_operations/get_responsive_search_ads.py b/examples/basic_operations/get_responsive_search_ads.py index 3482d9222..1103b9053 100755 --- a/examples/basic_operations/get_responsive_search_ads.py +++ b/examples/basic_operations/get_responsive_search_ads.py @@ -83,7 +83,7 @@ def ad_text_assets_to_strs(assets): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List responsive display ads for specified customer. " diff --git a/examples/basic_operations/pause_ad.py b/examples/basic_operations/pause_ad.py index ccca9ecc5..9572a3794 100755 --- a/examples/basic_operations/pause_ad.py +++ b/examples/basic_operations/pause_ad.py @@ -50,7 +50,7 @@ def main(client, customer_id, ad_group_id, ad_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Pauses an ad in the specified customer's ad group.") ) diff --git a/examples/basic_operations/remove_ad.py b/examples/basic_operations/remove_ad.py index dbbb9eb09..db6afb6a4 100755 --- a/examples/basic_operations/remove_ad.py +++ b/examples/basic_operations/remove_ad.py @@ -43,7 +43,7 @@ def main(client, customer_id, ad_group_id, ad_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Removes an ad from the specified customer's ad group.") ) diff --git a/examples/basic_operations/remove_ad_group.py b/examples/basic_operations/remove_ad_group.py index a85cfaddf..e5b99c852 100755 --- a/examples/basic_operations/remove_ad_group.py +++ b/examples/basic_operations/remove_ad_group.py @@ -39,7 +39,7 @@ def main(client, customer_id, ad_group_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Removes an ad group for the specified customer.") diff --git a/examples/basic_operations/remove_campaign.py b/examples/basic_operations/remove_campaign.py index 981bfa39a..6fe0dda02 100755 --- a/examples/basic_operations/remove_campaign.py +++ b/examples/basic_operations/remove_campaign.py @@ -39,7 +39,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Removes given campaign for the specified customer.") diff --git a/examples/basic_operations/remove_keyword.py b/examples/basic_operations/remove_keyword.py index 82124c0c9..5ddca11da 100755 --- a/examples/basic_operations/remove_keyword.py +++ b/examples/basic_operations/remove_keyword.py @@ -41,7 +41,7 @@ def main(client, customer_id, ad_group_id, criterion_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Removes given campaign for the specified customer.") ) diff --git a/examples/basic_operations/search_for_google_ads_fields.py b/examples/basic_operations/search_for_google_ads_fields.py index 162ba3311..8bc91ee43 100755 --- a/examples/basic_operations/search_for_google_ads_fields.py +++ b/examples/basic_operations/search_for_google_ads_fields.py @@ -96,7 +96,7 @@ def main(client, name_prefix, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists metadata for the specified artifact." diff --git a/examples/basic_operations/update_ad_group.py b/examples/basic_operations/update_ad_group.py index 3baa62da4..8c92ab7a6 100755 --- a/examples/basic_operations/update_ad_group.py +++ b/examples/basic_operations/update_ad_group.py @@ -55,7 +55,7 @@ def main(client, customer_id, ad_group_id, cpc_bid_micro_amount): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/basic_operations/update_campaign.py b/examples/basic_operations/update_campaign.py index 5a4fab52a..5d6f38451 100755 --- a/examples/basic_operations/update_campaign.py +++ b/examples/basic_operations/update_campaign.py @@ -55,7 +55,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Updates the given campaign for the specified customer." diff --git a/examples/basic_operations/update_keyword.py b/examples/basic_operations/update_keyword.py index 0ebb926f0..cb76d669d 100755 --- a/examples/basic_operations/update_keyword.py +++ b/examples/basic_operations/update_keyword.py @@ -47,7 +47,7 @@ def main(client, customer_id, ad_group_id, criterion_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Updates a keyword for the specified ad group.") ) diff --git a/examples/basic_operations/update_responsive_search_ad.py b/examples/basic_operations/update_responsive_search_ad.py index 5c4f90484..cd1fca5be 100755 --- a/examples/basic_operations/update_responsive_search_ad.py +++ b/examples/basic_operations/update_responsive_search_ad.py @@ -79,7 +79,7 @@ def main(client, customer_id, ad_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/billing/add_account_budget_proposal.py b/examples/billing/add_account_budget_proposal.py index 1d2b8f445..072088c48 100755 --- a/examples/billing/add_account_budget_proposal.py +++ b/examples/billing/add_account_budget_proposal.py @@ -80,7 +80,7 @@ def main(client, customer_id, billing_setup_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates an account budget proposal." diff --git a/examples/billing/add_billing_setup.py b/examples/billing/add_billing_setup.py index d69ed37a3..84668697a 100755 --- a/examples/billing/add_billing_setup.py +++ b/examples/billing/add_billing_setup.py @@ -185,7 +185,7 @@ def set_billing_setup_date_times(client, customer_id, billing_setup): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Creates a billing setup for a given customer.") diff --git a/examples/billing/get_account_budget_proposals.py b/examples/billing/get_account_budget_proposals.py index cfdfe3fcb..9033b9fa3 100755 --- a/examples/billing/get_account_budget_proposals.py +++ b/examples/billing/get_account_budget_proposals.py @@ -74,7 +74,7 @@ def main(client, customer_id, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists all account budget proposals." diff --git a/examples/billing/get_account_budgets.py b/examples/billing/get_account_budgets.py index 5164a9c2b..528557aaa 100755 --- a/examples/billing/get_account_budgets.py +++ b/examples/billing/get_account_budgets.py @@ -108,7 +108,7 @@ def micros_to_currency(micros): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/billing/get_billing_setup.py b/examples/billing/get_billing_setup.py index ca50f00f4..190efba82 100755 --- a/examples/billing/get_billing_setup.py +++ b/examples/billing/get_billing_setup.py @@ -70,7 +70,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists all billing setup objects for specified customer." diff --git a/examples/billing/get_invoices.py b/examples/billing/get_invoices.py index 863ec3227..e98d6e9d3 100755 --- a/examples/billing/get_invoices.py +++ b/examples/billing/get_invoices.py @@ -107,7 +107,7 @@ def micros_to_currency(micros): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Retrieves the invoices issued last month for a given billing setup." diff --git a/examples/billing/remove_billing_setup.py b/examples/billing/remove_billing_setup.py index 358a8eaaa..5d604819b 100755 --- a/examples/billing/remove_billing_setup.py +++ b/examples/billing/remove_billing_setup.py @@ -49,7 +49,7 @@ def main(client, customer_id, billing_setup_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/campaign_management/add_campaign_bid_modifier.py b/examples/campaign_management/add_campaign_bid_modifier.py index f20fdda9b..e4bfebb4b 100755 --- a/examples/campaign_management/add_campaign_bid_modifier.py +++ b/examples/campaign_management/add_campaign_bid_modifier.py @@ -80,7 +80,7 @@ def main(client, customer_id, campaign_id, bid_modifier_value): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/campaign_management/add_campaign_draft.py b/examples/campaign_management/add_campaign_draft.py index 278c9b2ef..42bb487b0 100755 --- a/examples/campaign_management/add_campaign_draft.py +++ b/examples/campaign_management/add_campaign_draft.py @@ -53,7 +53,7 @@ def main(client, customer_id, base_campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a campaign draft for the specified base campaign " diff --git a/examples/campaign_management/add_campaign_labels.py b/examples/campaign_management/add_campaign_labels.py index bc3f0723d..d9dfae753 100755 --- a/examples/campaign_management/add_campaign_labels.py +++ b/examples/campaign_management/add_campaign_labels.py @@ -68,7 +68,7 @@ def main(client, customer_id, label_id, campaign_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This code example adds a campaign label to a list of " diff --git a/examples/campaign_management/add_complete_campaigns_using_batch_job.py b/examples/campaign_management/add_complete_campaigns_using_batch_job.py index 48eac14f1..2919fc8be 100755 --- a/examples/campaign_management/add_complete_campaigns_using_batch_job.py +++ b/examples/campaign_management/add_complete_campaigns_using_batch_job.py @@ -631,7 +631,7 @@ def handle_googleads_exception(exception): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/campaign_management/create_experiment.py b/examples/campaign_management/create_experiment.py index d8b22b406..586c95e21 100644 --- a/examples/campaign_management/create_experiment.py +++ b/examples/campaign_management/create_experiment.py @@ -36,7 +36,7 @@ def main(client, customer_id, base_campaign_id): client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. base_campaign_id: the campaign ID to associate with the control arm of - the experiment. + the experiment. """ experiment = create_experiment_resource(client, customer_id) treatment_arm = create_experiment_arms( @@ -91,7 +91,7 @@ def create_experiment_arms(client, customer_id, base_campaign_id, experiment): client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. base_campaign_id: the campaign ID to associate with the control arm of - the experiment. + the experiment. experiment: the resource name for an experiment. Returns: @@ -108,7 +108,7 @@ def create_experiment_arms(client, customer_id, base_campaign_id, experiment): exa_1.campaigns.append( campaign_service.campaign_path(customer_id, base_campaign_id) ) - exa_1.trial = experiment + exa_1.experiment = experiment exa_1.name = "control arm" exa_1.traffic_split = 40 operations.append(operation_1) @@ -119,7 +119,7 @@ def create_experiment_arms(client, customer_id, base_campaign_id, experiment): operation_2 = client.get_type("ExperimentArmOperation") exa_2 = operation_2.create exa_2.control = False - exa_2.trial = experiment + exa_2.experiment = experiment exa_2.name = "experiment arm" exa_2.traffic_split = 60 operations.append(operation_2) @@ -215,7 +215,7 @@ def modify_draft_campaign(client, customer_id, draft_campaign): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Create a campaign experiment based on a campaign draft.") diff --git a/examples/campaign_management/get_all_disapproved_ads.py b/examples/campaign_management/get_all_disapproved_ads.py index 0f9a4dfa6..8ba1ec50d 100755 --- a/examples/campaign_management/get_all_disapproved_ads.py +++ b/examples/campaign_management/get_all_disapproved_ads.py @@ -80,7 +80,7 @@ def main(client, customer_id, campaign_id, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/campaign_management/get_campaigns_by_label.py b/examples/campaign_management/get_campaigns_by_label.py index c8f50f180..48296a3b1 100755 --- a/examples/campaign_management/get_campaigns_by_label.py +++ b/examples/campaign_management/get_campaigns_by_label.py @@ -76,7 +76,7 @@ def main(client, customer_id, label_id, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists all campaigns for specified customer." diff --git a/examples/campaign_management/set_ad_parameters.py b/examples/campaign_management/set_ad_parameters.py index c9ca1827d..35d25972e 100755 --- a/examples/campaign_management/set_ad_parameters.py +++ b/examples/campaign_management/set_ad_parameters.py @@ -70,9 +70,7 @@ def main(client, customer_id, ad_group_id, criterion_id): ) -def create_ad_parameter( - client, resource_name, parameter_index, insertion_text -): +def create_ad_parameter(client, resource_name, parameter_index, insertion_text): """Creates a new ad parameter create operation and returns it. There can be a maximum of two ad parameters per ad group criterion, one @@ -101,7 +99,7 @@ def create_ad_parameter( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") # Initializes a command line argument parser. parser = argparse.ArgumentParser( diff --git a/examples/campaign_management/update_campaign_criterion_bid_modifier.py b/examples/campaign_management/update_campaign_criterion_bid_modifier.py index f1525f770..61d314d8e 100755 --- a/examples/campaign_management/update_campaign_criterion_bid_modifier.py +++ b/examples/campaign_management/update_campaign_criterion_bid_modifier.py @@ -55,7 +55,7 @@ def main(client, customer_id, campaign_id, criterion_id, bid_modifier_value): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/campaign_management/validate_ad.py b/examples/campaign_management/validate_ad.py index 6d8169612..9b16d3bcb 100755 --- a/examples/campaign_management/validate_ad.py +++ b/examples/campaign_management/validate_ad.py @@ -114,7 +114,7 @@ def main(client, customer_id, ad_group_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/custom_logging_interceptor/get_campaigns.py b/examples/custom_logging_interceptor/get_campaigns.py index bc5ce4845..24849b132 100755 --- a/examples/custom_logging_interceptor/get_campaigns.py +++ b/examples/custom_logging_interceptor/get_campaigns.py @@ -13,10 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. """This example illustrates how to get all campaigns and log details to + Google Cloud Logging using a custom logging interceptor. """ - import argparse import sys @@ -24,8 +24,7 @@ from google.ads.googleads.errors import GoogleAdsException from cloud_logging_interceptor import CloudLoggingInterceptor - -_API_VERSION = "v11" +_API_VERSION = "v12" def main(client, customer_id): diff --git a/examples/error_handling/handle_keyword_policy_violations.py b/examples/error_handling/handle_keyword_policy_violations.py index 7a0cddb4b..a9aea6f1b 100755 --- a/examples/error_handling/handle_keyword_policy_violations.py +++ b/examples/error_handling/handle_keyword_policy_violations.py @@ -226,7 +226,7 @@ def request_exemption( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Demonstrates how to request an exemption for policy " diff --git a/examples/error_handling/handle_partial_failure.py b/examples/error_handling/handle_partial_failure.py index c377d1bff..21f8078ad 100755 --- a/examples/error_handling/handle_partial_failure.py +++ b/examples/error_handling/handle_partial_failure.py @@ -207,7 +207,7 @@ def print_results(client, response): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds an ad group for specified customer and campaign id." diff --git a/examples/error_handling/handle_rate_exceeded_error.py b/examples/error_handling/handle_rate_exceeded_error.py index 49a84edee..e64010e9f 100755 --- a/examples/error_handling/handle_rate_exceeded_error.py +++ b/examples/error_handling/handle_rate_exceeded_error.py @@ -174,7 +174,7 @@ def request_mutate_and_display_result(client, customer_id, operations): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Handles RateExceededError in an application.." diff --git a/examples/error_handling/handle_expanded_text_ad_policy_violations.py b/examples/error_handling/handle_responsive_search_ad_policy_violations.py similarity index 72% rename from examples/error_handling/handle_expanded_text_ad_policy_violations.py rename to examples/error_handling/handle_responsive_search_ad_policy_violations.py index e75f132d4..720de6d66 100755 --- a/examples/error_handling/handle_expanded_text_ad_policy_violations.py +++ b/examples/error_handling/handle_responsive_search_ad_policy_violations.py @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Requests an exemption for policy violations of an expanded text ad. +"""Requests an exemption for policy violations of a responsive search ad. If the request somehow fails with exceptions that are not policy finding errors, the example will stop instead of trying sending an exemption request. @@ -31,50 +31,48 @@ def main(client, customer_id, ad_group_id): Args: client: The Google Ads client. - customer_id: The customer ID for which to add the expanded text ad. - ad_group_id: The ad group ID to which to add an expanded text ad. + customer_id: The customer ID for which to add the responsive search ad. + ad_group_id: The ad group ID to which to add a responsive search ad. """ - ad_group_ad_service_client = client.get_service("AdGroupAdService") - - ad_group_ad_operation, ignorable_policy_topics = create_expanded_text_ad( + ad_group_ad_operation = create_responsive_search_ad( client, ad_group_ad_service_client, customer_id, ad_group_id ) + ignorable_policy_topics = [] try: - request_exemption( - customer_id, - ad_group_ad_service_client, - ad_group_ad_operation, - ignorable_policy_topics, + # Try sending a mutate request to add the ad group ad. + ad_group_ad_service_client.mutate_ad_group_ads( + customer_id=customer_id, operations=[ad_group_ad_operation] ) - except GoogleAdsException as ex: - print( - f"Request with ID '{ex.request_id}' failed with status " - f"'{ex.error.code().name}' and includes the following errors:" + except GoogleAdsException as googleads_exception: + # The request will always fail due to the policy violation in the + # ad's description. + ignorable_policy_topics = fetch_ignorable_policy_topics( + client, googleads_exception ) - for error in ex.failure.errors: - print(f"\tError with message '{error.message}'.") - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) + + request_exemption( + customer_id, + ad_group_ad_service_client, + ad_group_ad_operation, + ignorable_policy_topics, + ) -def create_expanded_text_ad( +def create_responsive_search_ad( client, ad_group_ad_service_client, customer_id, ad_group_id ): - """Create an expanded text ad that includes a policy violation. + """Create a responsive search ad that includes a policy violation. Args: client: The GoogleAds client instance. ad_group_ad_service_client: The AdGroupAdService client instance. - customer_id: The customer ID for which to add the expanded text ad. - ad_group_id: The ad group ID to which to add an expanded text ad. + customer_id: The customer ID for which to add the responsive search ad. + ad_group_id: The ad group ID to which to add a responsive search ad. Returns: - The attempted AdGroupAdOperation instance and a list of ignorable - policy topics. + The attempted AdGroupAdOperation instance. """ ad_group_resource_name = client.get_service("AdGroupService").ad_group_path( customer_id, ad_group_id @@ -87,34 +85,35 @@ def create_expanded_text_ad( # Set the ad group ad to PAUSED to prevent it from immediately serving. # Set to ENABLED once you've added targeting and the ad are ready to serve. ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED - # Sets the expanded text ad info on an ad. - expanded_text_ad_info = ad_group_ad.ad.expanded_text_ad - expanded_text_ad_info.headline_part1 = ( - f"Cruise to Mars #{str(uuid.uuid4())[0:13]}" + # Sets the responsive search ad info on an ad. + responsive_search_ad_info = ad_group_ad.ad.responsive_search_ad + + headline_1 = client.get_type("AdTextAsset") + headline_1.text = f"Cruise to Mars #{str(uuid.uuid4())[0:13]}" + headline_2 = client.get_type("AdTextAsset") + headline_2.text = "Best Space Cruise Line" + headline_3 = client.get_type("AdTextAsset") + headline_3.text = "Experience the Stars" + responsive_search_ad_info.headlines.extend( + [headline_1, headline_2, headline_3] ) - expanded_text_ad_info.headline_part2 = "Best Space Cruise Line" + # Intentionally use an ad text that violates policy by having too many # exclamation marks. - expanded_text_ad_info.description = "Buy your tickets now!!!!!!!" - ad_group_ad.ad.final_urls.append("http://www.example.com") + description_1 = client.get_type("AdTextAsset") + description_1.text = "Buy your tickets now!!!!!!!" + description_2 = client.get_type("AdTextAsset") + description_2.text = "Visit the Red Planet" + responsive_search_ad_info.descriptions.extend( + [description_1, description_2] + ) - ignorable_policy_topics = [] - try: - # Try sending a mutate request to add the ad group ad. - ad_group_ad_service_client.mutate_ad_group_ads( - customer_id=customer_id, operations=[ad_group_ad_operation] - ) - except GoogleAdsException as googleads_exception: - # The request will always fail due to the policy violation in the - # ad's description. - ignorable_policy_topics = fetch_ignorable_policy_topics( - client, googleads_exception - ) + ad_group_ad.ad.final_urls.append("https://www.example.com") - return ad_group_ad_operation, ignorable_policy_topics + return ad_group_ad_operation -# [START handle_expanded_text_ad_policy_violations] +# [START handle_responsive_search_ad_policy_violations] def fetch_ignorable_policy_topics(client, googleads_exception): """Collects all ignorable policy topics to be sent for exemption request. @@ -166,28 +165,28 @@ def fetch_ignorable_policy_topics(client, googleads_exception): # - policy_topic_entry.constraints return ignorable_policy_topics - # [END handle_expanded_text_ad_policy_violations] + # [END handle_responsive_search_ad_policy_violations] -# [START handle_expanded_text_ad_policy_violations_1] +# [START handle_responsive_search_ad_policy_violations_1] def request_exemption( customer_id, ad_group_ad_service_client, ad_group_ad_operation, ignorable_policy_topics, ): - """Sends exemption requests for creating an expanded text ad. + """Sends exemption requests for creating a responsive search ad. Args: - customer_id: The customer ID for which to add the expanded text ad. + customer_id: The customer ID for which to add the responsive search ad. ad_group_ad_service_client: The AdGroupAdService client instance. ad_group_ad_operation: The AdGroupAdOperation that returned policy violation(s). ignorable_policy_topics: The extracted list of policy topic entries. """ print( - "Attempting to add an expanded text ad again by requesting exemption " - "for its policy violations." + "Attempting to add a responsive search ad again by requesting " + "exemption for its policy violations." ) ad_group_ad_operation.policy_validation_parameter.ignorable_policy_topics.extend( ignorable_policy_topics @@ -196,20 +195,20 @@ def request_exemption( customer_id=customer_id, operations=[ad_group_ad_operation] ) print( - "Successfully added an expanded text ad with resource name " + "Successfully added a responsive search ad with resource name " f"'{response.results[0].resource_name}' for policy violation " "exemption." ) - # [END handle_expanded_text_ad_policy_violations_1] + # [END handle_responsive_search_ad_policy_violations_1] if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( - description="Requests an exemption for expanded text ad policy " + description="Requests an exemption for responsive search ad policy " "violations." ) # The following argument(s) should be provided to run the example. @@ -225,8 +224,20 @@ def request_exemption( "--ad_group_id", type=str, required=True, - help="The ad group ID to which to add an expanded text ad.", + help="The ad group ID to which to add a responsive search ad.", ) args = parser.parse_args() - main(googleads_client, args.customer_id, args.ad_group_id) + try: + main(googleads_client, args.customer_id, args.ad_group_id) + except GoogleAdsException as ex: + print( + f"Request with ID '{ex.request_id}' failed with status " + f"'{ex.error.code().name}' and includes the following errors:" + ) + for error in ex.failure.errors: + print(f"\tError with message '{error.message}'.") + if error.location: + for field_path_element in error.location.field_path_elements: + print(f"\t\tOn field: {field_path_element.field_name}") + sys.exit(1) diff --git a/examples/extensions/add_affiliate_location_extensions.py b/examples/extensions/add_affiliate_location_extensions.py index a0396818a..ffb416d10 100644 --- a/examples/extensions/add_affiliate_location_extensions.py +++ b/examples/extensions/add_affiliate_location_extensions.py @@ -434,7 +434,7 @@ def get_attribute_id_for_chain_id(client, feed_mapping): if __name__ == "__main__": # will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Demonstrates how to add Affiliate Location extensions." diff --git a/examples/extensions/add_business_profile_location_extensions.py b/examples/extensions/add_business_profile_location_extensions.py index c932a57a3..6ac4f9b0d 100644 --- a/examples/extensions/add_business_profile_location_extensions.py +++ b/examples/extensions/add_business_profile_location_extensions.py @@ -357,7 +357,7 @@ def get_business_profile_feed_mapping(client, customer_id, feed_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a feed that syncs feed items from a Business Profile " diff --git a/examples/extensions/add_call.py b/examples/extensions/add_call.py index c31d0cb36..a96151e24 100755 --- a/examples/extensions/add_call.py +++ b/examples/extensions/add_call.py @@ -123,7 +123,7 @@ def link_asset_to_account(client, customer_id, asset_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Adds a call extension to a specific account.") diff --git a/examples/extensions/add_geo_target.py b/examples/extensions/add_geo_target.py index 357edc2cc..5741aa962 100755 --- a/examples/extensions/add_geo_target.py +++ b/examples/extensions/add_geo_target.py @@ -69,7 +69,7 @@ def main(client, customer_id, feed_item_id, geo_target_constant_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a geo target to an extension feed item for targeting." diff --git a/examples/extensions/add_hotel_callout.py b/examples/extensions/add_hotel_callout.py index d667d04ff..8b0a350c7 100755 --- a/examples/extensions/add_hotel_callout.py +++ b/examples/extensions/add_hotel_callout.py @@ -110,7 +110,7 @@ def link_asset_to_account(client, customer_id, resource_names): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a hotel callout extension asset to the given account." diff --git a/examples/extensions/add_image_extension.py b/examples/extensions/add_image_extension.py index fd63abaa6..3630668c4 100755 --- a/examples/extensions/add_image_extension.py +++ b/examples/extensions/add_image_extension.py @@ -81,7 +81,7 @@ def main(client, customer_id, campaign_id, image_asset_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Adds an image extension to a campaign.") diff --git a/examples/extensions/add_lead_form_extension.py b/examples/extensions/add_lead_form_extension.py index 2e1101493..ab148acb3 100755 --- a/examples/extensions/add_lead_form_extension.py +++ b/examples/extensions/add_lead_form_extension.py @@ -173,7 +173,7 @@ def create_lead_form_extension( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This code example creates a lead form and a lead form " diff --git a/examples/extensions/add_prices.py b/examples/extensions/add_prices.py index 7dc00dc1f..1da5be574 100644 --- a/examples/extensions/add_prices.py +++ b/examples/extensions/add_prices.py @@ -184,7 +184,7 @@ def add_asset_to_account(client, customer_id, price_asset_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Add price asset for the specified customer id." diff --git a/examples/extensions/add_sitelinks.py b/examples/extensions/add_sitelinks.py index ec62c1780..352e4295b 100755 --- a/examples/extensions/add_sitelinks.py +++ b/examples/extensions/add_sitelinks.py @@ -216,7 +216,7 @@ def populate_ad_schedule( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds sitelinks to the specified campaign." diff --git a/examples/extensions/add_sitelinks_using_assets.py b/examples/extensions/add_sitelinks_using_assets.py index d894cd474..a7127a0f5 100755 --- a/examples/extensions/add_sitelinks_using_assets.py +++ b/examples/extensions/add_sitelinks_using_assets.py @@ -36,9 +36,7 @@ def main(client, customer_id, campaign_id): # Creates sitelink assets. resource_names = create_sitelink_assets(client, customer_id, campaign_id) # Associates the sitelinks at the campaign level. - link_sitelinks_to_campaign( - client, customer_id, campaign_id, resource_names - ) + link_sitelinks_to_campaign(client, customer_id, campaign_id, resource_names) def create_sitelink_assets(client, customer_id, campaign_id): @@ -141,7 +139,7 @@ def link_sitelinks_to_campaign( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds sitelinks to a campaign using feed services." diff --git a/examples/extensions/migrate_promotion_feed_to_asset.py b/examples/extensions/migrate_promotion_feed_to_asset.py index 23020072f..350186164 100755 --- a/examples/extensions/migrate_promotion_feed_to_asset.py +++ b/examples/extensions/migrate_promotion_feed_to_asset.py @@ -47,14 +47,10 @@ def main(client, customer_id, feed_item_id): ) # Get all campaign IDs associated with the extension feed item. - campaign_ids = get_targeted_campaign_ids( - client, customer_id, resource_name - ) + campaign_ids = get_targeted_campaign_ids(client, customer_id, resource_name) # Get all ad group IDs associated with the extension feed item. - ad_group_ids = get_targeted_ad_group_ids( - client, customer_id, resource_name - ) + ad_group_ids = get_targeted_ad_group_ids(client, customer_id, resource_name) # Create a new Promotion asset that matches the target extension feed item. promotion_asset_resource_name = create_promotion_asset_from_feed( @@ -413,7 +409,7 @@ def associate_asset_with_ad_groups( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Migrates a feed-based promotion extension to an " diff --git a/examples/extensions/remove_entire_sitelink_campaign_extension_setting.py b/examples/extensions/remove_entire_sitelink_campaign_extension_setting.py index c9dff79db..031506933 100644 --- a/examples/extensions/remove_entire_sitelink_campaign_extension_setting.py +++ b/examples/extensions/remove_entire_sitelink_campaign_extension_setting.py @@ -201,7 +201,7 @@ def create_extension_feed_item_mutate_operations( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Removes the entire sitelink campaign extension setting." diff --git a/examples/extensions/update_sitelink.py b/examples/extensions/update_sitelink.py index a1783cd98..2dd76dcee 100644 --- a/examples/extensions/update_sitelink.py +++ b/examples/extensions/update_sitelink.py @@ -67,7 +67,7 @@ def main(client, customer_id, feed_item_id, sitelink_text): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Update sitelink extension feed item with the specified " diff --git a/examples/extensions/update_sitelink_campaign_extension_setting.py b/examples/extensions/update_sitelink_campaign_extension_setting.py index 0e664405a..ee3e3912e 100644 --- a/examples/extensions/update_sitelink_campaign_extension_setting.py +++ b/examples/extensions/update_sitelink_campaign_extension_setting.py @@ -91,7 +91,7 @@ def main(client, customer_id, campaign_id, feed_item_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/feeds/create_feed_item_set.py b/examples/feeds/create_feed_item_set.py index 48eba280a..38a1bc711 100644 --- a/examples/feeds/create_feed_item_set.py +++ b/examples/feeds/create_feed_item_set.py @@ -73,7 +73,7 @@ def main(client, customer_id, feed_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a new feed item set for a specified feed." diff --git a/examples/feeds/get_feed_items_of_feed_item_set.py b/examples/feeds/get_feed_items_of_feed_item_set.py index e9bfd633e..5d0b11ce0 100755 --- a/examples/feeds/get_feed_items_of_feed_item_set.py +++ b/examples/feeds/get_feed_items_of_feed_item_set.py @@ -66,7 +66,7 @@ def main(client, customer_id, feed_id, feed_item_set_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Gets all feed items of the specified feed item set." diff --git a/examples/feeds/link_feed_item_set.py b/examples/feeds/link_feed_item_set.py index 6f84698df..cda8dc892 100644 --- a/examples/feeds/link_feed_item_set.py +++ b/examples/feeds/link_feed_item_set.py @@ -67,7 +67,7 @@ def main(client, customer_id, feed_id, feed_item_id, feed_item_set_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Links the specified feed item set to the specified feed item." diff --git a/examples/feeds/remove_feed_items.py b/examples/feeds/remove_feed_items.py index 591ada262..f2bdabbe2 100755 --- a/examples/feeds/remove_feed_items.py +++ b/examples/feeds/remove_feed_items.py @@ -59,7 +59,7 @@ def main(client, customer_id, feed_id, feed_item_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Removes feed items from a feed." diff --git a/examples/feeds/remove_flights_feed_item_attribute_value.py b/examples/feeds/remove_flights_feed_item_attribute_value.py index 694db7b13..00892f83a 100644 --- a/examples/feeds/remove_flights_feed_item_attribute_value.py +++ b/examples/feeds/remove_flights_feed_item_attribute_value.py @@ -56,9 +56,7 @@ def main( feed_item_operation = client.get_type("FeedItemOperation") # Get a map of the FlightPlaceholderFields to FeedAttributes. - placeholders_to_feed_attributes_map = get_feed( - client, customer_id, feed_id - ) + placeholders_to_feed_attributes_map = get_feed(client, customer_id, feed_id) # Remove the attribute from the feed item. flight_placeholder_field = client.enums.FlightPlaceholderFieldEnum[ @@ -257,7 +255,7 @@ def get_feed_item(client, customer_id, feed_id, feed_item_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Removes a feed item attribute value of a feed item in a " diff --git a/examples/feeds/update_flights_feed_item_string_attribute_value.py b/examples/feeds/update_flights_feed_item_string_attribute_value.py index 0407768b9..379d8ae73 100755 --- a/examples/feeds/update_flights_feed_item_string_attribute_value.py +++ b/examples/feeds/update_flights_feed_item_string_attribute_value.py @@ -276,7 +276,7 @@ def get_attribute_index(target_feed_item_attribute_value, feed_item): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Updates a feed item attribute value in a flights feed." diff --git a/examples/hotel_ads/add_hotel_ad.py b/examples/hotel_ads/add_hotel_ad.py index da112b82b..d1832fb7f 100755 --- a/examples/hotel_ads/add_hotel_ad.py +++ b/examples/hotel_ads/add_hotel_ad.py @@ -187,7 +187,7 @@ def add_hotel_campaign( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/hotel_ads/add_hotel_ad_group_bid_modifiers.py b/examples/hotel_ads/add_hotel_ad_group_bid_modifiers.py index 000636e80..2e73251b1 100755 --- a/examples/hotel_ads/add_hotel_ad_group_bid_modifiers.py +++ b/examples/hotel_ads/add_hotel_ad_group_bid_modifiers.py @@ -72,7 +72,7 @@ def main(client, customer_id, ad_group_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Adds an ad group bid modifier to a hotel ad group.") diff --git a/examples/hotel_ads/add_hotel_listing_group_tree.py b/examples/hotel_ads/add_hotel_listing_group_tree.py index fd095f121..72360ef01 100755 --- a/examples/hotel_ads/add_hotel_listing_group_tree.py +++ b/examples/hotel_ads/add_hotel_listing_group_tree.py @@ -459,7 +459,7 @@ def create_ad_group_criterion( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Shows how to add a hotel listing group tree with two " diff --git a/examples/migration/campaign_management/README.md b/examples/migration/campaign_management/README.md deleted file mode 100644 index 8db6a150f..000000000 --- a/examples/migration/campaign_management/README.md +++ /dev/null @@ -1,36 +0,0 @@ -Google Ads Client Library for Python - Migration examples - -This folder contains code examples that illustrate how to migrate from the -AdWords API to the Google Ads API in a step-by-step manner. The following code -examples are provided. - - -CampaignManagement -This folder contains a code example that shows how to create a Google Ads Search -campaign. The code example does the following operations: - -* Create a budget -* Create a campaign -* Create an ad group -* Create text ads -* Create keywords - - -The code example starts with create_complete_campaign_adwords_api_only.py that -shows the whole functionality developed in AdWords API. -create_complete_campaign_both_apis_phase_1.py through -create_complete_campaign_both_apis_phase_4.py shows how to migrate functionality -incrementally from the AdWords API to the Google Ads API. -create_complete_campaign_googleads_api_only.py shows the code example fully -transformed into using the Google Ads API. - -Running the examples: -1. cd into ./migration directory. -2. Run pip install -r requirements.txt to install dependencies. -3. Fill in the required authentication credentials, see -[here](https://github.com/googleads/google-ads-python#configuration-file-setup) -for the Google Ads API client library, and -[here](https://github.com/googleads/googleads-python-lib#getting-started) for -the AdWords client library. -4. Run each example from the command line, providing the required parameters. - diff --git a/examples/migration/campaign_management/create_complete_campaign_adwords_api_only.py b/examples/migration/campaign_management/create_complete_campaign_adwords_api_only.py deleted file mode 100755 index e079285da..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_adwords_api_only.py +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the help of AdWords Api. - -This code example is the first in a series of code examples that shows how to -create a Search campaign using the AdWords API, and then migrate it to Google -Ads API one functionality at a time. See other examples in this directory for -code examples in various stages of migration. - -This code example represents the initial state, where the AdWords API is used -to create a campaign budget, a Search campaign, ad groups, keywords and expanded -text ads. None of the functionality has yet been migrated to the Google Ads API. -""" - - -import datetime -import urllib.parse -import uuid - -from googleads import adwords - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] - - -def create_campaign_budget(client): - """Creates a new budget and returns the newly created budget ID. - - Args: - client: An instance of the google.ads.googleads.client.GoogleAdsClient - class. - - Returns: - (str) Budget ID of the newly created budget. - """ - budget_service = client.GetService("BudgetService", version="v201809") - budget = { - "name": "Interplanetary Cruise Budget #{}".format(uuid.uuid4()), - "amount": {"microAmount": "50000000"}, - "deliveryMethod": "STANDARD", - } - budget_operations = [{"operator": "ADD", "operand": budget}] - # Add budget. - results = budget_service.mutate(budget_operations) - created_budget = results["value"][0] - print( - "Budget with ID {} and name {} was created".format( - created_budget["budgetId"], created_budget["name"] - ) - ) - return created_budget["budgetId"] - - -def create_campaign(client, budget_id): - """Creates a new campaign and returns the newly created campaign ID. - - Args: - client: A google.ads.googleads.client.GoogleAdsClient instance. - budget_id: (str) Budget ID to be referenced while creating Campaign. - - Returns: - (str) Campaign ID of the newly created Campaign. - """ - campaign_service = client.GetService("CampaignService", version="v201809") - campaign = { - "name": "Interplanetary Cruise #{}".format(uuid.uuid4()), - "advertisingChannelType": "SEARCH", - # Recommendation: Set the campaign to PAUSED when creating it to stop the - # ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - "status": "PAUSED", - "biddingStrategyConfiguration": { - "biddingStrategyType": "MANUAL_CPC", - }, - "startDate": (datetime.datetime.now() + datetime.timedelta(1)).strftime( - "%Y%m%d" - ), - "endDate": (datetime.datetime.now() + datetime.timedelta(365)).strftime( - "%Y%m%d" - ), - # Budget (required) - note only the budget ID is required. - "budget": {"budgetId": budget_id}, - "networkSetting": { - "targetGoogleSearch": "true", - "targetSearchNetwork": "true", - }, - } - campaign_operations = [{"operator": "ADD", "operand": campaign}] - results = campaign_service.mutate(campaign_operations) - created_campaign = results["value"][0] - print( - "Created Campaign with ID {} and name {} was created".format( - created_campaign["id"], created_campaign["name"] - ) - ) - return created_campaign["id"] - - -def create_ad_group(client, campaign_id): - """Creates a new ad group and returns the new created ad group ID. - - Args: - client: A google.ads.googleads.client.GoogleAdsClient instance. - campaign_id: (str) The ID of the campaign under which to create a new - ad group. - - Returns: - (str) Ad group ID of the newly created ad group. - """ - ad_group_service = client.GetService("AdGroupService", "v201809") - ad_group = { - "name": "Earth to Mars Cruise #{}".format(uuid.uuid4()), - "campaignId": campaign_id, - "status": "ENABLED", - "biddingStrategyConfiguration": { - "bids": [ - { - # The 'xsi_type' field allows you to specify the xsi:type of the - # object being created. It's only necessary when you must provide - # an explicit type that the client library can't infer. - "xsi_type": "CpcBid", - "bid": {"microAmount": 10000000}, - } - ] - }, - "adGroupAdRotationMode": "OPTIMIZE", - } - - adgroup_operations = [{"operator": "ADD", "operand": ad_group}] - results = ad_group_service.mutate(adgroup_operations) - created_ad_group = results["value"][0] - print( - "Ad group with ID {} and name {} was created".format( - created_ad_group["id"], created_ad_group["name"] - ) - ) - return created_ad_group["id"] - - -def create_text_ads(client, ad_group_id): - """Creates text ads using the given ad group ID. - - Args: - client: A google.ads.googleads.client.GoogleAdsClient instance. - ad_group_id: (str) Ad group ID to be referenced when creating text ads. - """ - ad_group_service = client.GetService("AdGroupAdService", "v201809") - operations = [] - for i in range(NUMBER_OF_ADS): - operation = { - "xsi_type": "AdGroupAd", - "adGroupId": ad_group_id, - # Additional properties (non-required). - "status": "PAUSED", - "ad": { - "xsi_type": "ExpandedTextAd", - "headlinePart1": "Cruise #{} to Mars".format( - str(uuid.uuid4())[:8] - ), - "headlinePart2": "Best Space Cruise Line", - "headlinePart3": "For Your Loved Ones", - "description": "Buy your tickets now!", - "description2": "Discount ends soon", - "finalUrls": ["http://www.example.com/"], - }, - } - adgroup_operations = {"operator": "ADD", "operand": operation} - operations.append(adgroup_operations) - - results = ad_group_service.mutate(operations) - for result in results["value"]: - print( - "Expanded text ad with ID {} and " - "headline {}-{} {} was created".format( - result["ad"]["id"], - result["ad"]["headlinePart1"], - result["ad"]["headlinePart2"], - result["ad"]["headlinePart3"], - ) - ) - - -def create_keywords(client, ad_group_id, keywords_to_add): - """Populates keywords on a given ad group ID. - - Args: - client: A google.ads.googleads.client.GoogleAdsClient instance. - ad_group_id: (str) Ad group ID to be referenced when creating text ads. - keywords_to_add: (list) A list of keywords to be added to a given ad - group. - """ - ad_group_criterion_service = client.GetService( - "AdGroupCriterionService", "v201809" - ) - operations = [] - for keyword in keywords_to_add: - operation = { - "xsi_type": "BiddableAdGroupCriterion", - "adGroupId": ad_group_id, - "criterion": { - "xsi_type": "Keyword", - "text": keyword, - "matchType": "BROAD", - }, - "userStatus": "PAUSED", - "finalUrls": [ - "http://www.example.com/mars/cruise/?kw={}".format( - urllib.parse.quote(keyword) - ) - ], - } - create_keyword = {"operator": "ADD", "operand": operation} - operations.append(create_keyword) - - results = ad_group_criterion_service.mutate(operations) - for result in results["value"]: - print( - "Keyword with ad group ID {}, keyword ID {}, text {} and match" - "type {} was created".format( - result["adGroupId"], - result["criterion"]["id"], - result["criterion"]["text"], - result["criterion"]["matchType"], - ) - ) - - -if __name__ == "__main__": - # Initialize the client object. - # By default, it will read the config file from the Home Directory. - adwords_client = adwords.AdWordsClient.LoadFromStorage() - budget_id = create_campaign_budget(adwords_client) - campaign_id = create_campaign(adwords_client, budget_id) - ad_group_id = create_ad_group(adwords_client, campaign_id) - create_text_ads(adwords_client, ad_group_id) - create_keywords(adwords_client, ad_group_id, KEYWORDS_TO_ADD) diff --git a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_1.py b/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_1.py deleted file mode 100755 index e2b727656..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_1.py +++ /dev/null @@ -1,311 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the AdWords and Google Ads APIs. - -This code example is the second in a series of code examples that shows how to -create a Search ad_group using the AdWords API, and then migrate it to the -Google Ads API one functionality at a time. See other examples in this directory -for code examples in various stages of migration. - -In this code example, the functionality to create ad_group budget has been -migrated to the Google Ads API. The rest of the functionality - creating a -Search ad_group, ad groups, keywords and expanded text ads are done using the -AdWords API. -""" - -import argparse -import datetime -import sys -import urllib.parse -import uuid - -from googleads import adwords - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] -PAGE_SIZE = 1000 - - -def create_campaign_budget(client, customer_id): - """Creates a new campaign budget and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - - Returns: - A CampaignBudget. - """ - campaign_service = client.get_service("CampaignBudgetService") - operation = client.get_type("CampaignBudgetOperation") - criterion = operation.create - criterion.name = f"Interplanetary Cruise Budget {uuid.uuid4()}" - criterion.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD - criterion.amount_micros = 500000 - - try: - response = campaign_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[operation] - ) - campaign_budget_resource_name = response.results[0].resource_name - new_campaign_budget = get_campaign_budget( - client, customer_id, campaign_budget_resource_name - ) - print(f"Added budget named {new_campaign_budget.name}") - return new_campaign_budget - except GoogleAdsClient as ex: - handle_googleads_exception(ex) - - -def get_campaign_budget(client, customer_id, resource_name): - """Retrieves the CampaignBudget associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - resource_name: (str) Resource name associated with the newly created - campaign. - - Returns: - A CampaignBudget. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign_budget.id, - campaign_budget.name, - campaign_budget.resource_name - FROM campaign_budget - WHERE campaign_budget.resource_name = "{resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - budget = list(response)[0].campaign_budget - return budget - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_campaign(client, budget_id): - """Creates a new campaign and returns the newly created campaign ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - budget_id: (str) Budget ID to be referenced while creating Campaign. - - Returns: - (str) Campaign ID of the newly created Campaign. - """ - campaign_service = client.GetService("CampaignService", version="v201809") - campaign = { - "name": f"Interplanetary Cruise #{uuid.uuid4()}", - "advertisingChannelType": "SEARCH", - # Recommendation: Set the campaign to PAUSED when creating it to stop - # the ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - "status": "PAUSED", - "biddingStrategyConfiguration": { - "biddingStrategyType": "MANUAL_CPC", - }, - "startDate": (datetime.datetime.now() + datetime.timedelta(1)).strftime( - "%Y%m%d" - ), - "endDate": (datetime.datetime.now() + datetime.timedelta(365)).strftime( - "%Y%m%d" - ), - # Budget (required) - note only the budget ID is required. - "budget": {"budgetId": budget_id}, - "networkSetting": { - "targetGoogleSearch": "true", - "targetSearchNetwork": "true", - }, - } - campaign_operations = [{"operator": "ADD", "operand": campaign}] - results = campaign_service.mutate(campaign_operations) - created_campaign = results["value"][0] - print( - f'Created Campaign with ID {created_campaign["id"]} and name ' - f'{created_campaign["name"]} was created' - ) - return created_campaign["id"] - - -def create_ad_group(client, campaign_id): - """Creates a new ad group and returns the newly created ad group id. - - Args: - client: The ID of the campaign under which to create a new ad group. - campaign_id: (str) campaign ID to be referenced while creating ad group. - - Returns: - (str) Ad group ID of the newly created ad group. - """ - ad_group_service = client.GetService("AdGroupService", "v201809") - ad_group = { - "name": f"Earth to Mars Cruise #{uuid.uuid4()}", - "campaignId": campaign_id, - "status": "ENABLED", - "biddingStrategyConfiguration": { - "bids": [ - { - # The 'xsi_type' field allows you to specify the xsi:type of the - # object being created. It's only necessary when you must - # provide an explicit type that the client library can't infer. - "xsi_type": "CpcBid", - "bid": {"microAmount": 10000000}, - } - ] - }, - "adGroupAdRotationMode": "OPTIMIZE", - } - - adgroup_operations = [{"operator": "ADD", "operand": ad_group}] - results = ad_group_service.mutate(adgroup_operations) - created_ad_group = results["value"][0] - print( - f'Ad group with ID {created_ad_group["id"]} and name ' - f'{created_ad_group["name"]} was created' - ) - return created_ad_group["id"] - - -def create_text_ads(client, ad_group_id): - """Creates text ads using the given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) Ad group ID to be referenced when creating text ads. - """ - ad_group_service = client.GetService("AdGroupAdService", "v201809") - operations = [] - for i in range(NUMBER_OF_ADS): - operation = { - "xsi_type": "AdGroupAd", - "adGroupId": ad_group_id, - # Additional properties (non-required). - "status": "PAUSED", - "ad": { - "xsi_type": "ExpandedTextAd", - "headlinePart1": f"Cruise #{str(uuid.uuid4())[:8]} to Mars", - "headlinePart2": "Best Space Cruise Line", - "headlinePart3": "For Your Loved Ones", - "description": "Buy your tickets now!", - "description2": "Discount ends soon", - "finalUrls": ["http://www.example.com/"], - }, - } - adgroup_operations = {"operator": "ADD", "operand": operation} - operations.append(adgroup_operations) - - results = ad_group_service.mutate(operations) - for result in results["value"]: - print( - f'Expanded text ad with ID {result["ad"]["id"]} and headline ' - f'{result["ad"]["headlinePart1"]}-' - f'{result["ad"]["headlinePart2"]} ' - f'{result["ad"]["headlinePart3"]} was created' - ) - - -def create_keywords(client, ad_group_id, keywords_to_add): - """Populates keywords on a given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) ad group ID to be referenced while creating text ads. - keywords_to_add: (list) A list of keywords to be added to a given ad - group. - """ - ad_group_criterion_service = client.GetService( - "AdGroupCriterionService", "v201809" - ) - operations = [] - for keyword in keywords_to_add: - operation = { - "xsi_type": "BiddableAdGroupCriterion", - "adGroupId": ad_group_id, - "criterion": { - "xsi_type": "Keyword", - "text": keyword, - "matchType": "BROAD", - }, - "userStatus": "PAUSED", - "finalUrls": [ - ( - "http://www.example.com/mars/cruise/" - f"?kw={urllib.parse.quote(keyword)}" - ) - ], - } - create_keyword = {"operator": "ADD", "operand": operation} - operations.append(create_keyword) - - results = ad_group_criterion_service.mutate(operations) - for result in results["value"]: - print( - f'Keyword with ad group ID {result["adGroupId"]}, keyword ID ' - f'{result["criterion"]["id"]}, text ' - f'{result["criterion"]["text"]} and match' - f'type {result["criterion"]["matchType"]} was created' - ) - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # Initialize client object. - # It will read the config file. The default file path is the Home Directory. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - adwords_client = adwords.AdWordsClient.LoadFromStorage() - - parser = argparse.ArgumentParser( - description="Lists all campaigns for specified customer." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - budget = create_campaign_budget(googleads_client, args.customer_id) - campaign_id = create_campaign(adwords_client, budget.id) - ad_group_id = create_ad_group(adwords_client, campaign_id) - create_text_ads(adwords_client, ad_group_id) - create_keywords(adwords_client, ad_group_id, KEYWORDS_TO_ADD) diff --git a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_2.py b/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_2.py deleted file mode 100755 index 8de8b8c90..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_2.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the AdWords and Google Ads APIs. - -This code example is the third in a series of code examples that shows how to -create a Search campaign using the AdWords API, and then migrate it to the -Google Ads API one functionality at a time. See other examples in this directory -for code examples in various stages of migration. - -In this code example, the functionality to create campaign budget and search -campaign have been migrated to the Google Ads API. The rest of the functionality -- creating ad groups, keywords and expanded text ads are done using the -AdWords API. -""" - -import argparse -import datetime -import sys -import urllib.parse -import uuid - -from googleads import adwords - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] -PAGE_SIZE = 1000 - - -def create_campaign_budget(client, customer_id): - """Creates a new campaign budget and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - - Returns: - A CampaignBudget. - """ - campaign_service = client.get_service("CampaignBudgetService") - operation = client.get_type("CampaignBudgetOperation") - criterion = operation.create - criterion.name = f"Interplanetary Cruise Budget {uuid.uuid4()}" - criterion.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD - criterion.amount_micros = 500000 - - try: - response = campaign_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[operation] - ) - campaign_budget_resource_name = response.results[0].resource_name - new_campaign_budget = get_campaign_budget( - client, customer_id, campaign_budget_resource_name - ) - print(f"Added budget named {new_campaign_budget.name}") - return new_campaign_budget - except GoogleAdsClient as ex: - handle_googleads_exception(ex) - - -def get_campaign_budget(client, customer_id, resource_name): - """Retrieves the CampaignBudget associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - resource_name: (str) Resource name associated with the newly created - campaign. - - Returns: - A CampaignBudget. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign_budget.id, - campaign_budget.name, - campaign_budget.resource_name - FROM campaign_budget - WHERE campaign_budget.resource_name = "{resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - budget = list(response)[0].campaign_budget - return budget - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_campaign(client, customer_id, campaign_budget): - """Creates a new campaign and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_budget: A CampaignBudget. - - Returns: - A Campaign. - """ - operation = client.get_type("CampaignOperation") - campaign = operation.create - campaign_service = client.get_service("CampaignService") - campaign.name = f"Interplanetary Cruise#{uuid.uuid4()}" - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.SEARCH - ) - # Recommendation: Set the campaign to PAUSED when creating it to stop the - # ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - campaign.manual_cpc.enhanced_cpc_enabled = True - campaign.campaign_budget = campaign_budget.resource_name - campaign.network_settings.target_google_search = True - campaign.network_settings.target_search_network = True - campaign.network_settings.target_content_network = False - campaign.network_settings.target_partner_search_network = False - campaign.start_date = ( - datetime.datetime.now() + datetime.timedelta(1) - ).strftime("%Y%m%d") - campaign.end_date = ( - datetime.datetime.now() + datetime.timedelta(365) - ).strftime("%Y%m%d") - - try: - response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[operation] - ) - campaign_resource_name = response.results[0].resource_name - new_campaign = get_campaign( - client, customer_id, campaign_resource_name - ) - print(f"Added campaign named {new_campaign.name}") - return new_campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_campaign(client, customer_id, campaign_resource_name): - """Retrieves the Campaign associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_resource_name: (str) Resource name associated with the newly - created campaign budget. - - Returns: - A Campaign. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign.id, - campaign.name, - campaign.resource_name - FROM campaign - WHERE campaign.resource_name = "{campaign_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - campaign = list(response)[0].campaign - return campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_ad_group(client, campaign_id): - """Creates a new ad group and returns the newly created ad group id. - - Args: - client: The ID of the campaign under which to create a new ad group. - campaign_id: (str) campaign ID to be referenced while creating ad group. - - Returns: - (str) Ad group ID of the newly created ad group. - """ - ad_group_service = client.GetService("AdGroupService", "v201809") - ad_group = { - "name": f"Earth to Mars Cruise #{uuid.uuid4()}", - "campaignId": campaign_id, - "status": "ENABLED", - "biddingStrategyConfiguration": { - "bids": [ - { - # The 'xsi_type' field allows you to specify the xsi:type of the - # object being created. It's only necessary when you must - # provide an explicit type that the client library can't infer. - "xsi_type": "CpcBid", - "bid": {"microAmount": 10000000}, - } - ] - }, - "adGroupAdRotationMode": "OPTIMIZE", - } - - adgroup_operations = [{"operator": "ADD", "operand": ad_group}] - results = ad_group_service.mutate(adgroup_operations) - created_ad_group = results["value"][0] - print( - f'Ad group with ID {created_ad_group["id"]} and name ' - f'{created_ad_group["name"]} was created' - ) - return created_ad_group["id"] - - -def create_text_ads(client, ad_group_id): - """Creates text ads using the given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) Ad group ID to be referenced when creating text ads. - """ - ad_group_service = client.GetService("AdGroupAdService", "v201809") - operations = [] - for i in range(NUMBER_OF_ADS): - operation = { - "xsi_type": "AdGroupAd", - "adGroupId": ad_group_id, - # Additional properties (non-required). - "status": "PAUSED", - "ad": { - "xsi_type": "ExpandedTextAd", - "headlinePart1": f"Cruise #{str(uuid.uuid4())[:8]} to Mars", - "headlinePart2": "Best Space Cruise Line", - "headlinePart3": "For Your Loved Ones", - "description": "Buy your tickets now!", - "description2": "Discount ends soon", - "finalUrls": ["http://www.example.com/"], - }, - } - adgroup_operations = {"operator": "ADD", "operand": operation} - operations.append(adgroup_operations) - - results = ad_group_service.mutate(operations) - for result in results["value"]: - print( - f'Expanded text ad with ID {result["ad"]["id"]} and headline ' - f'{result["ad"]["headlinePart1"]}-' - f'{result["ad"]["headlinePart2"]} ' - f'{result["ad"]["headlinePart3"]} was created' - ) - - -def create_keywords(client, ad_group_id, keywords_to_add): - """Populates keywords on a given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) ad group ID to be referenced while creating text ads. - keywords_to_add: (list) A list of keywords to be added to the ad group. - """ - ad_group_criterion_service = client.GetService( - "AdGroupCriterionService", "v201809" - ) - operations = [] - for keyword in keywords_to_add: - operation = { - "xsi_type": "BiddableAdGroupCriterion", - "adGroupId": ad_group_id, - "criterion": { - "xsi_type": "Keyword", - "text": keyword, - "matchType": "BROAD", - }, - "userStatus": "PAUSED", - "finalUrls": [ - ( - "http://www.example.com/mars/cruise/" - f"?kw={urllib.parse.quote(keyword)}" - ) - ], - } - create_keyword = {"operator": "ADD", "operand": operation} - operations.append(create_keyword) - - results = ad_group_criterion_service.mutate(operations) - for result in results["value"]: - print( - f'Keyword with ad group ID {result["adGroupId"]}, keyword ID ' - f'{result["criterion"]["id"]}, text ' - f'{result["criterion"]["text"]} and match' - f'type {result["criterion"]["matchType"]} was created' - ) - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # Initialize client object. - # It will read the config file. The default file path is the Home Directory. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - adwords_client = adwords.AdWordsClient.LoadFromStorage() - - parser = argparse.ArgumentParser( - description="Lists all campaigns for specified customer." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - budget = create_campaign_budget(googleads_client, args.customer_id) - campaign = create_campaign(googleads_client, args.customer_id, budget) - ad_group_id = create_ad_group(adwords_client, campaign.id) - create_text_ads(adwords_client, ad_group_id) - create_keywords(adwords_client, ad_group_id, KEYWORDS_TO_ADD) diff --git a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_3.py b/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_3.py deleted file mode 100755 index fd69347d6..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_3.py +++ /dev/null @@ -1,377 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the AdWords and Google Ads APIs. - -This code example is the fourth in a series of code examples that shows how to -create a Search campaign using the AdWords API, and then migrate it to the -Google Ads API one functionality at a time. See other examples in this directory -for code examples in various stages of migration. - -In this code example, the functionality to create campaign budget and search -campaign have been migrated to the Google Ads API. The rest of the functionality -- creating ad groups, keywords and expanded text ads are done using the AdWords -API. -""" - -import argparse -import datetime -import sys -import urllib.parse -import uuid - -from googleads import adwords - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] -PAGE_SIZE = 1000 - - -def create_campaign_budget(client, customer_id): - """Creates a new campaign budget and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - - Returns: - A CampaignBudget. - """ - campaign_service = client.get_service("CampaignBudgetService") - operation = client.get_type("CampaignBudgetOperation") - criterion = operation.create - criterion.name = f"Interplanetary Cruise Budget {uuid.uuid4()}" - criterion.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD - criterion.amount_micros = 500000 - - try: - response = campaign_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[operation] - ) - campaign_budget_resource_name = response.results[0].resource_name - new_campaign_budget = get_campaign_budget( - client, customer_id, campaign_budget_resource_name - ) - print(f"Added budget named {new_campaign_budget.name}") - return new_campaign_budget - except GoogleAdsClient as ex: - handle_googleads_exception(ex) - - -def get_campaign_budget(client, customer_id, resource_name): - """Retrieves the CampaignBudget associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - resource_name: (str) Resource name associated with the newly created - campaign. - - Returns: - A CampaignBudget. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign_budget.id, - campaign_budget.name, - campaign_budget.resource_name - FROM campaign_budget - WHERE campaign_budget.resource_name = "{resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - budget = list(response)[0].campaign_budget - return budget - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_campaign(client, customer_id, campaign_budget): - """Creates a new campaign and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_budget: A CampaignBudget. - - Returns: - A Campaign. - """ - operation = client.get_type("CampaignOperation") - campaign = operation.create - campaign_service = client.get_service("CampaignService") - campaign.name = f"Interplanetary Cruise#{uuid.uuid4()}" - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.SEARCH - ) - # Recommendation: Set the campaign to PAUSED when creating it to stop the - # ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - campaign.manual_cpc.enhanced_cpc_enabled = True - campaign.campaign_budget = campaign_budget.resource_name - campaign.network_settings.target_google_search = True - campaign.network_settings.target_search_network = True - campaign.network_settings.target_content_network = False - campaign.network_settings.target_partner_search_network = False - campaign.start_date = ( - datetime.datetime.now() + datetime.timedelta(1) - ).strftime("%Y%m%d") - campaign.end_date = ( - datetime.datetime.now() + datetime.timedelta(365) - ).strftime("%Y%m%d") - - try: - response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[operation] - ) - campaign_resource_name = response.results[0].resource_name - new_campaign = get_campaign( - client, customer_id, campaign_resource_name - ) - print(f"Added campaign named {new_campaign.name}") - return new_campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_campaign(client, customer_id, campaign_resource_name): - """Retrieves the Campaign associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_resource_name: (str) Resource name associated with the newly - created campaign budget. - - Returns: - A Campaign. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign.id, - campaign.name, - campaign.resource_name - FROM campaign - WHERE campaign.resource_name = "{campaign_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - campaign = list(response)[0].campaign - return campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_ad_group(client, customer_id, campaign): - """Creates a new ad group and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign: A Campaign. - - Returns: - An AdGroup. - """ - operation = client.get_type("AdGroupOperation") - adgroup = operation.create - adgroup_service = client.get_service("AdGroupService") - adgroup.name = f"Earth to Mars Cruises #{uuid.uuid4()}" - adgroup.campaign = campaign.resource_name - adgroup.status = client.enums.AdGroupStatusEnum.ENABLED - adgroup.type = client.enums.AdGroupTypeEnum.SEARCH_STANDARD - adgroup.cpc_bid_micros = 10000000 - - try: - response = adgroup_service.mutate_ad_groups( - customer_id=customer_id, operations=[operation] - ) - ad_group_resource_name = response.results[0].resource_name - ad_group = get_ad_group(client, customer_id, ad_group_resource_name) - print(f"Added AdGroup named {ad_group.name}") - return ad_group - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_ad_group(client, customer_id, ad_group_resource_name): - """Retrieves an AdGroup associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group_resource_name: (str) Resource name associated with the newly - created Ad group. - - Returns: - An AdGroup. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - ad_group.id, - ad_group.name, - ad_group.resource_name - FROM ad_group - WHERE ad_group.resource_name = "{ad_group_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - adGroup = list(response)[0].ad_group - return adGroup - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_text_ads(client, ad_group_id): - """Creates text ads using the given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) Ad group ID to be referenced when creating text ads. - """ - ad_group_service = client.GetService("AdGroupAdService", "v201809") - operations = [] - for i in range(NUMBER_OF_ADS): - operation = { - "xsi_type": "AdGroupAd", - "adGroupId": ad_group_id, - # Additional properties (non-required). - "status": "PAUSED", - "ad": { - "xsi_type": "ExpandedTextAd", - "headlinePart1": f"Cruise #{str(uuid.uuid4())[:8]} to Mars", - "headlinePart2": "Best Space Cruise Line", - "headlinePart3": "For Your Loved Ones", - "description": "Buy your tickets now!", - "description2": "Discount ends soon", - "finalUrls": ["http://www.example.com/"], - }, - } - adgroup_operations = {"operator": "ADD", "operand": operation} - operations.append(adgroup_operations) - - results = ad_group_service.mutate(operations) - for result in results["value"]: - print( - f'Expanded text ad with ID {result["ad"]["id"]} and headline ' - f'{result["ad"]["headlinePart1"]}-' - f'{result["ad"]["headlinePart2"]} ' - f'{result["ad"]["headlinePart3"]} was created' - ) - - -def create_keywords(client, ad_group_id, keywords_to_add): - """Populates keywords on a given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) ad group ID to be referenced while creating text ads. - keywords_to_add: (list) A list of keywords to be added to a given ad - group. - """ - ad_group_criterion_service = client.GetService( - "AdGroupCriterionService", "v201809" - ) - operations = [] - for keyword in keywords_to_add: - operation = { - "xsi_type": "BiddableAdGroupCriterion", - "adGroupId": ad_group_id, - "criterion": { - "xsi_type": "Keyword", - "text": keyword, - "matchType": "BROAD", - }, - "userStatus": "PAUSED", - "finalUrls": [ - ( - "http://www.example.com/mars/cruise/" - f"?kw={urllib.parse.quote(keyword)}" - ) - ], - } - create_keyword = {"operator": "ADD", "operand": operation} - operations.append(create_keyword) - - results = ad_group_criterion_service.mutate(operations) - for result in results["value"]: - print( - f'Keyword with ad group ID {result["adGroupId"]}, keyword ID ' - f'{result["criterion"]["id"]}, text ' - f'{result["criterion"]["text"]} and match' - f'type {result["criterion"]["matchType"]} was created' - ) - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # Initialize client object. - # It will read the config file. The default file path is the Home Directory. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - adwords_client = adwords.AdWordsClient.LoadFromStorage() - - parser = argparse.ArgumentParser( - description="Lists all campaigns for specified customer." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - budget = create_campaign_budget(googleads_client, args.customer_id) - campaign = create_campaign(googleads_client, args.customer_id, budget) - ad_group = create_ad_group(googleads_client, args.customer_id, campaign) - create_text_ads(adwords_client, ad_group.id) - create_keywords(adwords_client, ad_group.id, KEYWORDS_TO_ADD) diff --git a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_4.py b/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_4.py deleted file mode 100755 index aab9e459f..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_both_apis_phase_4.py +++ /dev/null @@ -1,439 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the AdWords and Google Ads APIs. - -This code example is the fifth in a series of code examples that shows how to -create a Search campaign using the AdWords API, and then migrate it to the -Google Ads API one functionality at a time. See other examples in this directory -for code examples in various stages of migration. - -In this code example, the functionality to create campaign budget and search -campaign have been migrated to the Google Ads API. The rest of the functionality -- creating ad groups, keywords and expanded text ads are done using the AdWords -API. -""" - -import argparse -import datetime -import sys -import urllib.parse -import uuid - -from googleads import adwords - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] -PAGE_SIZE = 1000 - - -def create_campaign_budget(client, customer_id): - """Creates a new campaign budget and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - - Returns: - A CampaignBudget. - """ - campaign_service = client.get_service("CampaignBudgetService") - operation = client.get_type("CampaignBudgetOperation") - criterion = operation.create - criterion.name = f"Interplanetary Cruise Budget {uuid.uuid4()}" - criterion.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD - criterion.amount_micros = 500000 - - try: - response = campaign_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[operation] - ) - campaign_budget_resource_name = response.results[0].resource_name - new_campaign_budget = get_campaign_budget( - client, customer_id, campaign_budget_resource_name - ) - print(f"Added budget named {new_campaign_budget.name}") - return new_campaign_budget - except GoogleAdsClient as ex: - handle_googleads_exception(ex) - - -def get_campaign_budget(client, customer_id, resource_name): - """Retrieves the CampaignBudget associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - resource_name: (str) Resource name associated with the newly created - campaign. - - Returns: - A CampaignBudget. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign_budget.id, - campaign_budget.name, - campaign_budget.resource_name - FROM campaign_budget - WHERE campaign_budget.resource_name = "{resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - budget = list(response)[0].campaign_budget - return budget - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_campaign(client, customer_id, campaign_budget): - """Creates a new campaign and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_budget: A CampaignBudget. - - Returns: - A Campaign. - """ - operation = client.get_type("CampaignOperation") - campaign = operation.create - campaign_service = client.get_service("CampaignService") - campaign.name = f"Interplanetary Cruise#{uuid.uuid4()}" - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.SEARCH - ) - # Recommendation: Set the campaign to PAUSED when creating it to stop the - # ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - campaign.manual_cpc.enhanced_cpc_enabled = True - campaign.campaign_budget = campaign_budget.resource_name - campaign.network_settings.target_google_search = True - campaign.network_settings.target_search_network = True - campaign.network_settings.target_content_network = False - campaign.network_settings.target_partner_search_network = False - campaign.start_date = ( - datetime.datetime.now() + datetime.timedelta(1) - ).strftime("%Y%m%d") - campaign.end_date = ( - datetime.datetime.now() + datetime.timedelta(365) - ).strftime("%Y%m%d") - - try: - response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[operation] - ) - campaign_resource_name = response.results[0].resource_name - new_campaign = get_campaign( - client, customer_id, campaign_resource_name - ) - print(f"Added campaign named {new_campaign.name}") - return new_campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_campaign(client, customer_id, campaign_resource_name): - """Retrieves the Campaign associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_resource_name: (str) Resource name associated with the newly - created campaign budget. - - Returns: - A Campaign. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign.id, - campaign.name, - campaign.resource_name - FROM campaign - WHERE campaign.resource_name = "{campaign_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - campaign = list(response)[0].campaign - return campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_ad_group(client, customer_id, campaign): - """Creates a new ad group and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign: A Campaign. - - Returns: - An AdGroup. - """ - operation = client.get_type("AdGroupOperation") - adgroup = operation.create - adgroup_service = client.get_service("AdGroupService") - adgroup.name = f"Earth to Mars Cruises #{uuid.uuid4()}" - adgroup.campaign = campaign.resource_name - adgroup.status = client.enums.AdGroupStatusEnum.ENABLED - adgroup.type = client.enums.AdGroupTypeEnum.SEARCH_STANDARD - adgroup.cpc_bid_micros = 10000000 - - try: - response = adgroup_service.mutate_ad_groups( - customer_id=customer_id, operations=[operation] - ) - ad_group_resource_name = response.results[0].resource_name - ad_group = get_ad_group(client, customer_id, ad_group_resource_name) - print(f"Added AdGroup named {ad_group.name}") - return ad_group - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_ad_group(client, customer_id, ad_group_resource_name): - """Retrieves an AdGroup associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group_resource_name: (str) Resource name associated with the newly - created Ad group. - - Returns: - An AdGroup. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - ad_group.id, - ad_group.name, - ad_group.resource_name - FROM ad_group - WHERE ad_group.resource_name = "{ad_group_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - adGroup = list(response)[0].ad_group - return adGroup - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_text_ads(client, customer_id, ad_group): - """Creates new text ads in a given ad group. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group: A AdGroup instance. - """ - adgroup_service = client.get_service("AdGroupAdService") - - operations = [] - for i in range(0, NUMBER_OF_ADS): - operation = client.get_type("AdGroupAdOperation") - ad_group_operation = operation.create - ad_group_operation.ad_group = ad_group.resource_name - ad_group_operation.status = client.enums.AdGroupAdStatusEnum.PAUSED - ad_group_operation.ad.expanded_text_ad.headline_part1 = ( - f"Cruise to Mars #{str(uuid.uuid4())[:4]}" - ) - ad_group_operation.ad.expanded_text_ad.headline_part2 = ( - "Best Space Cruise Line" - ) - ad_group_operation.ad.expanded_text_ad.description = ( - "Buy your tickets now!" - ) - ad_group_operation.ad.final_urls.append("http://www.example.com") - operations.append(operation) - - try: - ad_group_ad_response = adgroup_service.mutate_ad_group_ads( - customer_id=customer_id, operations=operations - ) - new_ad_resource_names = [ - row.resource_name for row in ad_group_ad_response.results - ] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - new_ads = get_ads(client, customer_id, new_ad_resource_names) - for new_ad in new_ads: - print( - f"Created expanded text ad with ID {new_ad.ad.id}, status " - f"{new_ad.status} and headline " - f"{new_ad.ad.expanded_text_ad.headline_part1}." - f"{new_ad.ad.expanded_text_ad.headline_part2}" - ) - - -def get_ads(client, customer_id, new_ad_resource_names): - """Retrieves a list of AdGroupAds. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - new_ad_resource_names: (str) Resource name associated with the Ad group. - - Returns: - A list of AdGroupAds. - """ - - def formatter(given_string): - """Assigns ' ' to names of resources. - - This produces a formatted string that can be used within an IN clause. - Args: - given_string: (str) The string to be formatted. - Returns: - The formatted string. - """ - results = [] - for i in given_string: - results.append(repr(i)) - return ",".join(results) - - resource_names = formatter(new_ad_resource_names) - - ga_service = client.get_service("GoogleAdsService") - query = f""" - SELECT - ad_group_ad.ad.id, - ad_group_ad.ad.expanded_text_ad.headline_part1, - ad_group_ad.ad.expanded_text_ad.headline_part2, - ad_group_ad.status, - ad_group_ad.ad.final_urls, - ad_group_ad.resource_name - FROM ad_group_ad - WHERE ad_group_ad.resource_name in ({resource_names})""" - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - return [row.ad_group_ad for row in response.results] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_keywords(client, ad_group_id, keywords_to_add): - """Populates keywords on a given ad group ID. - - Args: - client: An instance of the googleads.adwords.AdWordsClient class. - ad_group_id: (str) ad group ID to be referenced while creating text ads. - keywords_to_add: (list) A list of keywords to be added to a given ad - group. - """ - ad_group_criterion_service = client.GetService( - "AdGroupCriterionService", "v201809" - ) - operations = [] - for keyword in keywords_to_add: - operation = { - "xsi_type": "BiddableAdGroupCriterion", - "adGroupId": ad_group_id, - "criterion": { - "xsi_type": "Keyword", - "text": keyword, - "matchType": "BROAD", - }, - "userStatus": "PAUSED", - "finalUrls": [ - ( - "http://www.example.com/mars/cruise/" - f"?kw={urllib.parse.quote(keyword)}" - ) - ], - } - create_keyword = {"operator": "ADD", "operand": operation} - operations.append(create_keyword) - - results = ad_group_criterion_service.mutate(operations) - for result in results["value"]: - print( - f'Keyword with ad group ID {result["adGroupId"]}, keyword ID ' - f'{result["criterion"]["id"]}, text ' - f'{result["criterion"]["text"]} and match' - f'type {result["criterion"]["matchType"]} was created' - ) - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # Initialize client object. - # It will read the config file. The default file path is the Home Directory. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - adwords_client = adwords.AdWordsClient.LoadFromStorage() - - parser = argparse.ArgumentParser( - description="Lists all campaigns for specified customer." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - budget = create_campaign_budget(googleads_client, args.customer_id) - campaign = create_campaign(googleads_client, args.customer_id, budget) - ad_group = create_ad_group(googleads_client, args.customer_id, campaign) - create_text_ads(googleads_client, args.customer_id, ad_group) - create_keywords(adwords_client, ad_group.id, KEYWORDS_TO_ADD) diff --git a/examples/migration/campaign_management/create_complete_campaign_googleads_api_only.py b/examples/migration/campaign_management/create_complete_campaign_googleads_api_only.py deleted file mode 100755 index 02fa5db21..000000000 --- a/examples/migration/campaign_management/create_complete_campaign_googleads_api_only.py +++ /dev/null @@ -1,497 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example creates a search campaign with the help of Google Ads API only. - -This code example is the last in a series of code examples that shows how to -create a Search campaign using the AdWords API, and then migrate it to the -Google Ads API one functionality at a time. See other examples in this directory -for code examples in various stages of migration. - -This code example represents the final state, where all the functionality - create a -campaign budget, a Search campaign, ad groups, keywords and expanded text ads have been -migrated to using the Google Ads API. The AdWords API is not used. -""" - -import argparse -import datetime -import sys -import uuid - - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - -# Number of ads being added/updated in this code example. -NUMBER_OF_ADS = 5 -# The list of keywords being added in this code example. -KEYWORDS_TO_ADD = ["mars cruise", "space hotel"] -PAGE_SIZE = 1000 - - -def create_campaign_budget(client, customer_id): - """Creates a new campaign budget and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - - Returns: - A CampaignBudget. - """ - campaign_service = client.get_service("CampaignBudgetService") - operation = client.get_type("CampaignBudgetOperation") - criterion = operation.create - criterion.name = f"Interplanetary Cruise Budget {uuid.uuid4()}" - criterion.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD - criterion.amount_micros = 500000 - - try: - response = campaign_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[operation] - ) - campaign_budget_resource_name = response.results[0].resource_name - new_campaign_budget = get_campaign_budget( - client, customer_id, campaign_budget_resource_name - ) - print(f"Added budget named {new_campaign_budget.name}") - return new_campaign_budget - except GoogleAdsClient as ex: - handle_googleads_exception(ex) - - -def get_campaign_budget(client, customer_id, resource_name): - """Retrieves the CampaignBudget associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - resource_name: (str) Resource name associated with the newly created - campaign. - - Returns: - A CampaignBudget. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign_budget.id, - campaign_budget.name, - campaign_budget.resource_name - FROM campaign_budget - WHERE campaign_budget.resource_name = "{resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - budget = list(response)[0].campaign_budget - return budget - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_campaign(client, customer_id, campaign_budget): - """Creates a new campaign and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_budget: A CampaignBudget. - - Returns: - A Campaign. - """ - operation = client.get_type("CampaignOperation") - campaign = operation.create - campaign_service = client.get_service("CampaignService") - campaign.name = f"Interplanetary Cruise#{uuid.uuid4()}" - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.SEARCH - ) - # Recommendation: Set the campaign to PAUSED when creating it to stop the - # ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - campaign.manual_cpc.enhanced_cpc_enabled = True - campaign.campaign_budget = campaign_budget.resource_name - campaign.network_settings.target_google_search = True - campaign.network_settings.target_search_network = True - campaign.network_settings.target_content_network = False - campaign.network_settings.target_partner_search_network = False - campaign.start_date = ( - datetime.datetime.now() + datetime.timedelta(1) - ).strftime("%Y%m%d") - campaign.end_date = ( - datetime.datetime.now() + datetime.timedelta(365) - ).strftime("%Y%m%d") - - try: - response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[operation] - ) - campaign_resource_name = response.results[0].resource_name - new_campaign = get_campaign( - client, customer_id, campaign_resource_name - ) - print(f"Added campaign named {new_campaign.name}") - return new_campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_campaign(client, customer_id, campaign_resource_name): - """Retrieves the Campaign associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign_resource_name: (str) Resource name associated with the newly - created campaign budget. - - Returns: - A Campaign. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - campaign.id, - campaign.name, - campaign.resource_name - FROM campaign - WHERE campaign.resource_name = "{campaign_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - campaign = list(response)[0].campaign - return campaign - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_ad_group(client, customer_id, campaign): - """Creates a new ad group and returns it. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - campaign: A Campaign. - - Returns: - An AdGroup. - """ - operation = client.get_type("AdGroupOperation") - adgroup = operation.create - adgroup_service = client.get_service("AdGroupService") - adgroup.name = f"Earth to Mars Cruises #{uuid.uuid4()}" - adgroup.campaign = campaign.resource_name - adgroup.status = client.enums.AdGroupStatusEnum.ENABLED - adgroup.type = client.enums.AdGroupTypeEnum.SEARCH_STANDARD - adgroup.cpc_bid_micros = 10000000 - - try: - response = adgroup_service.mutate_ad_groups( - customer_id=customer_id, operations=[operation] - ) - ad_group_resource_name = response.results[0].resource_name - ad_group = get_ad_group(client, customer_id, ad_group_resource_name) - print(f"Added AdGroup named {ad_group.name}") - return ad_group - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def get_ad_group(client, customer_id, ad_group_resource_name): - """Retrieves an AdGroup associated with the given resource name. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group_resource_name: (str) Resource name associated with the newly - created Ad group. - - Returns: - An AdGroup. - """ - ga_service = client.get_service("GoogleAdsService") - query = f''' - SELECT - ad_group.id, - ad_group.name, - ad_group.resource_name - FROM ad_group - WHERE ad_group.resource_name = "{ad_group_resource_name}"''' - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - adGroup = list(response)[0].ad_group - return adGroup - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_text_ads(client, customer_id, ad_group): - """Creates new text ads in a given ad group. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group: A AdGroup instance. - """ - adgroup_service = client.get_service("AdGroupAdService") - - operations = [] - for i in range(0, NUMBER_OF_ADS): - operation = client.get_type("AdGroupAdOperation") - ad_group_operation = operation.create - ad_group_operation.ad_group = ad_group.resource_name - ad_group_operation.status = client.enums.AdGroupAdStatusEnum.PAUSED - ad_group_operation.ad.expanded_text_ad.headline_part1 = ( - f"Cruise to Mars #{str(uuid.uuid4())[:4]}" - ) - ad_group_operation.ad.expanded_text_ad.headline_part2 = ( - "Best Space Cruise Line" - ) - ad_group_operation.ad.expanded_text_ad.description = ( - "Buy your tickets now!" - ) - ad_group_operation.ad.final_urls.append("http://www.example.com") - operations.append(operation) - - try: - ad_group_ad_response = adgroup_service.mutate_ad_group_ads( - customer_id=customer_id, operations=operations - ) - new_ad_resource_names = [ - row.resource_name for row in ad_group_ad_response.results - ] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - new_ads = get_ads(client, customer_id, new_ad_resource_names) - for new_ad in new_ads: - print( - f"Created expanded text ad with ID {new_ad.ad.id}, status " - f"{new_ad.status} and headline " - f"{new_ad.ad.expanded_text_ad.headline_part1}." - f"{new_ad.ad.expanded_text_ad.headline_part2}" - ) - - -def get_ads(client, customer_id, new_ad_resource_names): - """Retrieves a list of AdGroupAds. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - new_ad_resource_names: (str) Resource name associated with the Ad group. - - Returns: - A list of AdGroupAds. - """ - - def formatter(given_string): - """Assigns ' ' to names of resources. - - This produces a formatted string that can be used within an IN clause. - Args: - given_string: (str) The string to be formatted. - Returns: - The formatted string. - """ - results = [] - for i in given_string: - results.append(repr(i)) - return ",".join(results) - - resource_names = formatter(new_ad_resource_names) - - ga_service = client.get_service("GoogleAdsService") - query = f""" - SELECT - ad_group_ad.ad.id, - ad_group_ad.ad.expanded_text_ad.headline_part1, - ad_group_ad.ad.expanded_text_ad.headline_part2, - ad_group_ad.status, - ad_group_ad.ad.final_urls, - ad_group_ad.resource_name - FROM ad_group_ad - WHERE ad_group_ad.resource_name in ({resource_names})""" - - request = client.get_type("SearchGoogleAdsRequest") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - return [row.ad_group_ad for row in response.results] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def create_keywords(client, customer_id, ad_group, keywords_to_add): - """Creates new keywords on a given ad group. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - ad_group: An AdGroup. - keywords_to_add: keywords_to_add: (list) A list of keywords which are to - be added to a given ad group. - """ - ad_group_criterion_service = client.get_service( - "AdGroupCriterionService", version="v4" - ) - - ad_group_criterion_operations = [] - for keyword in keywords_to_add: - operation = client.get_type("AdGroupCriterionOperation", version="v4") - ad_group_criterion_operation = operation.create - ad_group_criterion_operation.ad_group = ad_group.resource_name - ad_group_criterion_operation.status = ( - client.enums.AdGroupCriterionStatusEnum.ENABLED - ) - ad_group_criterion_operation.keyword.text = keyword - ad_group_criterion_operation.keyword.match_type = ( - client.enums.KeywordMatchTypeEnum.EXACT - ) - ad_group_criterion_operations.append(operation) - - try: - ad_group_criterion_response = ( - ad_group_criterion_service.mutate_ad_group_criteria( - customer_id=customer_id, - operations=ad_group_criterion_operations, - ) - ) - new_ad_resource_names = [ - row.resource_name for row in ad_group_criterion_response.results - ] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - new_keywords = get_keywords(client, customer_id, new_ad_resource_names) - - for criterion in new_keywords: - print( - f"Keyword with text {criterion.keyword.text}, id=" - f"{criterion.criterion_id} and match type " - f"{criterion.keyword.match_type} was created" - ) - - -def get_keywords(client, customer_id, keyword_resource_names): - """Retrieves a list of AdGroupCriterion. - - Args: - client: A GoogleAdsClient instance. - customer_id: (str) Customer ID associated with the account. - keyword_resource_names: (str) Resource name associated with the newly - created ad group criterion. - - Returns: - A list of AdGroupCriterion. - """ - resource_names = formatter(keyword_resource_names) - ga_service = client.get_service("GoogleAdsService", version="v4") - query = f""" - SELECT - ad_group.id, - ad_group.status, - ad_group_criterion.criterion_id, - ad_group_criterion.keyword.text, - ad_group_criterion.keyword.match_type - FROM ad_group_criterion - WHERE ad_group_criterion.type = "KEYWORD" - AND ad_group.status = "ENABLED" - AND ad_group_criterion.status IN ("ENABLED", "PAUSED") - AND ad_group_criterion.resource_name IN ({resource_names})""" - - request = client.get_type("SearchGoogleAdsRequest", version="v4") - request.customer_id = customer_id - request.query = query - request.page_size = PAGE_SIZE - - try: - response = ga_service.search(request=request) - return [row.ad_group_criterion for row in response.results] - except GoogleAdsException as ex: - handle_googleads_exception(ex) - - -def formatter(given_string): - """This helper function is used to assign ' ' to names of resources - so that this formatted string can be used within an IN clause. - - Args: - given_string: (str) The string to be formatted. - """ - results = [] - for i in given_string: - results.append(repr(i)) - return ",".join(results) - - -def handle_googleads_exception(exception): - print( - f'Request with ID "{exception.request_id}" failed with status ' - f'"{exception.error.code().name}" and includes the following errors:' - ) - for error in exception.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) - - -if __name__ == "__main__": - # Initialize client object. - # It will read the config file. The default file path is the Home Directory. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - - parser = argparse.ArgumentParser( - description="Lists all campaigns for specified customer." - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - args = parser.parse_args() - budget = create_campaign_budget(googleads_client, args.customer_id) - campaign = create_campaign(googleads_client, args.customer_id, budget) - ad_group = create_ad_group(googleads_client, args.customer_id, campaign) - create_text_ads(googleads_client, args.customer_id, ad_group) - create_keywords( - googleads_client, args.customer_id, ad_group, KEYWORDS_TO_ADD - ) diff --git a/examples/migration/campaign_management/requirements.txt b/examples/migration/campaign_management/requirements.txt deleted file mode 100644 index 669fd154e..000000000 --- a/examples/migration/campaign_management/requirements.txt +++ /dev/null @@ -1,31 +0,0 @@ -appdirs -attrs -cached-property -cachetools -certifi -chardet -defusedxml -google-ads -google-api-core -google-auth -google-auth-oauthlib -googleads -googleapis-common-protos -grpcio -idna -isodate -lxml -oauthlib -protobuf -pyasn1 -pyasn1-modules -pytz -PyYAML -requests -requests-oauthlib -requests-toolbelt -rsa -six -urllib3 -xmltodict -zeep diff --git a/examples/migration/campaign_report_to_csv.py b/examples/misc/campaign_report_to_csv.py old mode 100644 new mode 100755 similarity index 76% rename from examples/migration/campaign_report_to_csv.py rename to examples/misc/campaign_report_to_csv.py index b17a9833d..35094284f --- a/examples/migration/campaign_report_to_csv.py +++ b/examples/misc/campaign_report_to_csv.py @@ -26,7 +26,6 @@ Write to file output.csv in the same directory as script without headers. $ python get_campaign_stats_to_csv.py -c 0123456789 -o output.csv """ - import argparse import csv import sys @@ -70,58 +69,46 @@ def main(client, customer_id, output_file, write_headers): search_request.customer_id = customer_id search_request.query = query stream = ga_service.search_stream(search_request) - try: - with open(file_path, "w", newline="") as f: - writer = csv.writer(f) - - # Define a list of headers for the first row. - headers = [ - "Account", - "Date", - "Campaign", - "Impressions", - "Clicks", - "Cost", - ] - - # If the write_headers flag was passed, write header row to the CSV - if write_headers: - writer.writerow(headers) - - for batch in stream: - for row in batch.results: - # Use the CSV writer to write the individual GoogleAdsRow - # fields returned in the SearchGoogleAdsStreamResponse. - writer.writerow( - [ - row.customer.descriptive_name, - row.segments.date, - row.campaign.name, - row.metrics.impressions, - row.metrics.clicks, - row.metrics.cost_micros, - ] - ) - - print(f"Customer {customer_id} report written to {output_file}") - except GoogleAdsException as ex: - print( - f'Request with ID "{ex.request_id}" failed with status ' - f'"{ex.error.code().name}" and includes the following errors:' - ) - for error in ex.failure.errors: - print(f'\tError with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) + with open(file_path, "w", newline="") as f: + writer = csv.writer(f) + + # Define a list of headers for the first row. + headers = [ + "Account", + "Date", + "Campaign", + "Impressions", + "Clicks", + "Cost", + ] + + # If the write_headers flag was passed, write header row to the CSV + if write_headers: + writer.writerow(headers) + + for batch in stream: + for row in batch.results: + # Use the CSV writer to write the individual GoogleAdsRow + # fields returned in the SearchGoogleAdsStreamResponse. + writer.writerow( + [ + row.customer.descriptive_name, + row.segments.date, + row.campaign.name, + row.metrics.impressions, + row.metrics.clicks, + row.metrics.cost_micros, + ] + ) + + print(f"Customer {customer_id} report written to {output_file}") if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - google_ads_client = GoogleAdsClient.load_from_storage(version="v11") + google_ads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Retrieves a campaign stats and writes to CSV file." @@ -155,9 +142,21 @@ def main(client, customer_id, output_file, write_headers): ) args = parser.parse_args() - main( - google_ads_client, - args.customer_id, - args.output_file, - args.write_headers, - ) + try: + main( + google_ads_client, + args.customer_id, + args.output_file, + args.write_headers, + ) + except GoogleAdsException as ex: + print( + f'Request with ID "{ex.request_id}" failed with status ' + f'"{ex.error.code().name}" and includes the following errors:' + ) + for error in ex.failure.errors: + print(f'\tError with message "{error.message}".') + if error.location: + for field_path_element in error.location.field_path_elements: + print(f"\t\tOn field: {field_path_element.field_name}") + sys.exit(1) diff --git a/examples/misc/get_all_image_assets.py b/examples/misc/get_all_image_assets.py index d6d57da83..36f6d27a9 100755 --- a/examples/misc/get_all_image_assets.py +++ b/examples/misc/get_all_image_assets.py @@ -65,7 +65,7 @@ def main(client, customer_id, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List all image assets for specified customer." diff --git a/examples/misc/get_all_videos_and_images.py b/examples/misc/get_all_videos_and_images.py index 60f2fa672..79e42f919 100755 --- a/examples/misc/get_all_videos_and_images.py +++ b/examples/misc/get_all_videos_and_images.py @@ -54,7 +54,7 @@ def main(client, customer_id, page_size): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="List all videos and images for specified customer." diff --git a/examples/misc/navigate_search_result_pages_caching_tokens.py b/examples/misc/navigate_search_result_pages_caching_tokens.py index 2a6c6c6a9..4db3c28b4 100755 --- a/examples/misc/navigate_search_result_pages_caching_tokens.py +++ b/examples/misc/navigate_search_result_pages_caching_tokens.py @@ -177,7 +177,7 @@ def cache_next_page_token(page_tokens, page, page_number): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/misc/set_custom_client_timeouts.py b/examples/misc/set_custom_client_timeouts.py index e5575f505..6de50c0d0 100755 --- a/examples/misc/set_custom_client_timeouts.py +++ b/examples/misc/set_custom_client_timeouts.py @@ -156,7 +156,7 @@ def make_unary_call(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Demonstrates custom client timeouts in the context of " diff --git a/examples/misc/upload_image.py b/examples/misc/upload_image.py index 0fa4935df..464dfe6c8 100644 --- a/examples/misc/upload_image.py +++ b/examples/misc/upload_image.py @@ -47,7 +47,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser(description="Upload an image from a URL.") # The following argument(s) should be provided to run the example. diff --git a/examples/misc/upload_image_asset.py b/examples/misc/upload_image_asset.py index 3e9ec8793..0f3ac0f68 100644 --- a/examples/misc/upload_image_asset.py +++ b/examples/misc/upload_image_asset.py @@ -63,7 +63,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Upload an image asset from a URL." diff --git a/examples/misc/upload_media_bundle.py b/examples/misc/upload_media_bundle.py index 79f866e26..0e3c40b6d 100755 --- a/examples/misc/upload_media_bundle.py +++ b/examples/misc/upload_media_bundle.py @@ -48,7 +48,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser(description="Uploads a media bundle.") # The following argument(s) should be provided to run the example. diff --git a/examples/planning/add_keyword_plan.py b/examples/planning/add_keyword_plan.py index 2731ccf6c..4c5927b08 100755 --- a/examples/planning/add_keyword_plan.py +++ b/examples/planning/add_keyword_plan.py @@ -284,7 +284,7 @@ def create_keyword_plan_negative_campaign_keywords( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a keyword plan for specified customer." diff --git a/examples/planning/forecast_reach.py b/examples/planning/forecast_reach.py index 98820ce5c..43791663f 100755 --- a/examples/planning/forecast_reach.py +++ b/examples/planning/forecast_reach.py @@ -12,9 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""This code example generates a video ads reach forecast. -""" - +"""This code example generates a video ads reach forecast.""" import argparse import math @@ -23,7 +21,6 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException - ONE_MILLION = 1.0e6 @@ -43,12 +40,7 @@ def main(client, customer_id): show_plannable_locations(client) show_plannable_products(client, location_id) - forecast_manual_mix( - client, customer_id, location_id, currency_code, budget - ) - forecast_suggested_mix( - client, customer_id, location_id, currency_code, budget - ) + forecast_manual_mix(client, customer_id, location_id, currency_code, budget) def show_plannable_locations(client): @@ -210,57 +202,10 @@ def forecast_manual_mix( # [END forecast_reach_3] -# [START forecast_reach_1] -def forecast_suggested_mix( - client, customer_id, location_id, currency_code, budget -): - """Pulls a forecast for a product mix based on your set of preferences. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: The customer ID for the reach forecast. - product_mix: The product mix for the reach forecast. - location_id: The location ID to plan for. - currency_code: Three-character ISO 4217 currency code. - budget: Budget to allocate to the plan. - """ - preferences = client.get_type("Preferences") - preferences.has_guaranteed_price = True - preferences.starts_with_sound = True - preferences.is_skippable = False - preferences.top_content_only = True - preferences.ad_length = ( - client.enums.ReachPlanAdLengthEnum.FIFTEEN_OR_TWENTY_SECONDS - ) - - reach_plan_service = client.get_service("ReachPlanService") - request = client.get_type("GenerateProductMixIdeasRequest") - request.customer_id = customer_id - request.plannable_location_id = location_id - request.preferences = preferences - request.currency_code = currency_code - request.budget_micros = int(budget * ONE_MILLION) - mix_response = reach_plan_service.generate_product_mix_ideas( - request=request - ) - - product_mix = [] - for product in mix_response.product_allocation: - planned_product = client.get_type("PlannedProduct") - planned_product.plannable_product_code = product.plannable_product_code - planned_product.budget_micros = product.budget_micros - product_mix.append(planned_product) - - request_reach_curve( - client, customer_id, product_mix, location_id, currency_code - ) - # [END forecast_reach_1] - - if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Generates video ads reach forecast." diff --git a/examples/planning/generate_forecast_metrics.py b/examples/planning/generate_forecast_metrics.py index a79f069c2..a6691d256 100755 --- a/examples/planning/generate_forecast_metrics.py +++ b/examples/planning/generate_forecast_metrics.py @@ -58,7 +58,7 @@ def main(client, customer_id, keyword_plan_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Generates forecast metrics for a keyword plan." diff --git a/examples/planning/generate_keyword_ideas.py b/examples/planning/generate_keyword_ideas.py index ab11fee53..bae13174d 100755 --- a/examples/planning/generate_keyword_ideas.py +++ b/examples/planning/generate_keyword_ideas.py @@ -117,7 +117,7 @@ def map_locations_ids_to_resource_names(client, location_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Generates keyword ideas from a list of seed keywords." diff --git a/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py b/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py index 82cbdd2e2..dc71da705 100755 --- a/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py +++ b/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py @@ -79,7 +79,7 @@ def main(client, customer_id, ad_group_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Gets all available ad group criterion CPC bid " diff --git a/examples/planning/get_campaign_criterion_bid_modifier_simulations.py b/examples/planning/get_campaign_criterion_bid_modifier_simulations.py index cfae882a8..d296949f0 100755 --- a/examples/planning/get_campaign_criterion_bid_modifier_simulations.py +++ b/examples/planning/get_campaign_criterion_bid_modifier_simulations.py @@ -83,7 +83,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Gets all available criterion bid modifier simulations " diff --git a/examples/recommendations/apply_recommendation.py b/examples/recommendations/apply_recommendation.py index 702c378b0..6bb3595ca 100755 --- a/examples/recommendations/apply_recommendation.py +++ b/examples/recommendations/apply_recommendation.py @@ -58,7 +58,7 @@ def main(client, customer_id, recommendation_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Applies a specified recommendation.") diff --git a/examples/recommendations/detect_and_apply_recommendations.py b/examples/recommendations/detect_and_apply_recommendations.py index 7d24aef87..141bf1a84 100755 --- a/examples/recommendations/detect_and_apply_recommendations.py +++ b/examples/recommendations/detect_and_apply_recommendations.py @@ -103,7 +103,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Detectes and applies a specified recommendation.") diff --git a/examples/recommendations/dismiss_recommendation.py b/examples/recommendations/dismiss_recommendation.py index adae1c8f1..faf355939 100755 --- a/examples/recommendations/dismiss_recommendation.py +++ b/examples/recommendations/dismiss_recommendation.py @@ -46,7 +46,7 @@ def main(client, customer_id, recommendation_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Dismisses a recommendation with the given ID.") diff --git a/examples/recommendations/get_text_ad_recommendations.py b/examples/recommendations/get_text_ad_recommendations.py index eb2a0fde6..2f6a6e8f1 100755 --- a/examples/recommendations/get_text_ad_recommendations.py +++ b/examples/recommendations/get_text_ad_recommendations.py @@ -65,7 +65,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Lists TEXT_AD recommendations for specified customer." diff --git a/examples/remarketing/add_combined_rule_user_list.py b/examples/remarketing/add_combined_rule_user_list.py index dc3fc9a51..b6eefc3dd 100644 --- a/examples/remarketing/add_combined_rule_user_list.py +++ b/examples/remarketing/add_combined_rule_user_list.py @@ -127,7 +127,7 @@ def build_visited_site_rule_info(client, url): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a combination user list containing users that are " diff --git a/examples/remarketing/add_conversion_action.py b/examples/remarketing/add_conversion_action.py index 3383ee792..bbd96cde7 100755 --- a/examples/remarketing/add_conversion_action.py +++ b/examples/remarketing/add_conversion_action.py @@ -65,7 +65,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a conversion action for specified customer." diff --git a/examples/remarketing/add_conversion_based_user_list.py b/examples/remarketing/add_conversion_based_user_list.py index 626f78b3f..f4b34dedc 100644 --- a/examples/remarketing/add_conversion_based_user_list.py +++ b/examples/remarketing/add_conversion_based_user_list.py @@ -80,7 +80,7 @@ def main(client, customer_id, conversion_action_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a basic user list based on conversion actions." diff --git a/examples/remarketing/add_custom_audience.py b/examples/remarketing/add_custom_audience.py index 845d479eb..fb6adfb63 100755 --- a/examples/remarketing/add_custom_audience.py +++ b/examples/remarketing/add_custom_audience.py @@ -124,7 +124,7 @@ def create_custom_audience_member(client, member_type, value): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a custom audience for a specified customer." diff --git a/examples/remarketing/add_customer_match_user_list.py b/examples/remarketing/add_customer_match_user_list.py index bfd541586..34910f2a5 100755 --- a/examples/remarketing/add_customer_match_user_list.py +++ b/examples/remarketing/add_customer_match_user_list.py @@ -345,7 +345,7 @@ def normalize_and_hash(s): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a customer match user list for specified customer." diff --git a/examples/remarketing/add_dynamic_remarketing_asset.py b/examples/remarketing/add_dynamic_remarketing_asset.py index 6da9fa956..682fd1c86 100755 --- a/examples/remarketing/add_dynamic_remarketing_asset.py +++ b/examples/remarketing/add_dynamic_remarketing_asset.py @@ -193,7 +193,7 @@ def link_asset_set_to_campaign( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds an asset for use in dynamic remarketing." diff --git a/examples/remarketing/add_expression_rule_user_list.py b/examples/remarketing/add_expression_rule_user_list.py index f3369b8c9..bc6f98e30 100644 --- a/examples/remarketing/add_expression_rule_user_list.py +++ b/examples/remarketing/add_expression_rule_user_list.py @@ -124,7 +124,7 @@ def build_visited_site_rule_info(client, url): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a rule-based user list defined by an expression " diff --git a/examples/remarketing/add_flights_feed.py b/examples/remarketing/add_flights_feed.py index c90ae8dc3..fbb7e3413 100755 --- a/examples/remarketing/add_flights_feed.py +++ b/examples/remarketing/add_flights_feed.py @@ -413,7 +413,7 @@ def get_placeholder_fields_map(client, customer_id, feed_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a flights feed for specified customer." diff --git a/examples/remarketing/add_logical_user_list.py b/examples/remarketing/add_logical_user_list.py index e7ac87258..d7f5181e1 100644 --- a/examples/remarketing/add_logical_user_list.py +++ b/examples/remarketing/add_logical_user_list.py @@ -86,7 +86,7 @@ def main(client, customer_id, user_list_ids): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a combination user list containing users that are " diff --git a/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py b/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py index e1b6ea347..a3fa711d3 100644 --- a/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py +++ b/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py @@ -264,9 +264,7 @@ def upload_image_asset(client, customer_id, image_url, asset_name): # [START add_merchant_center_dynamic_remarketing_campaign_3] -def attach_user_list( - client, customer_id, ad_group_resource_name, user_list_id -): +def attach_user_list(client, customer_id, ad_group_resource_name, user_list_id): """Targets a user list with an ad group. Args: @@ -303,7 +301,7 @@ def attach_user_list( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/remarketing/add_real_estate_feed.py b/examples/remarketing/add_real_estate_feed.py index 1bf08822a..d5fa970ca 100644 --- a/examples/remarketing/add_real_estate_feed.py +++ b/examples/remarketing/add_real_estate_feed.py @@ -434,7 +434,7 @@ def get_placeholder_fields_map(client, customer_id, feed_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a real estate feed for specified customer." diff --git a/examples/remarketing/add_remarketing_action.py b/examples/remarketing/add_remarketing_action.py index d8e345f1d..52bc49101 100755 --- a/examples/remarketing/add_remarketing_action.py +++ b/examples/remarketing/add_remarketing_action.py @@ -143,7 +143,7 @@ def print_remarketing_action_attributes(remarketing_action): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Adds a remarketing action for specified customer." diff --git a/examples/remarketing/set_up_advanced_remarketing.py b/examples/remarketing/set_up_advanced_remarketing.py index f82183868..300792e59 100644 --- a/examples/remarketing/set_up_advanced_remarketing.py +++ b/examples/remarketing/set_up_advanced_remarketing.py @@ -174,7 +174,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Creates a rule-based user list defined by an expression " diff --git a/examples/remarketing/set_up_remarketing.py b/examples/remarketing/set_up_remarketing.py index c117a4a13..fd9a0d83d 100755 --- a/examples/remarketing/set_up_remarketing.py +++ b/examples/remarketing/set_up_remarketing.py @@ -358,7 +358,7 @@ def modify_campaign_bids( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Demonstrates various operations involved in remarketing." diff --git a/examples/remarketing/update_audience_target_restriction.py b/examples/remarketing/update_audience_target_restriction.py index 63b07e978..b65d68a75 100644 --- a/examples/remarketing/update_audience_target_restriction.py +++ b/examples/remarketing/update_audience_target_restriction.py @@ -168,7 +168,7 @@ def update_targeting_setting( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Updates the audience target restriction of a given ad " diff --git a/examples/remarketing/upload_call_conversion.py b/examples/remarketing/upload_call_conversion.py index be35f234b..e1f760491 100644 --- a/examples/remarketing/upload_call_conversion.py +++ b/examples/remarketing/upload_call_conversion.py @@ -112,7 +112,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Imports offline call conversion values for calls related " diff --git a/examples/remarketing/upload_conversion_adjustment.py b/examples/remarketing/upload_conversion_adjustment.py index fdb268b40..07fde9e69 100644 --- a/examples/remarketing/upload_conversion_adjustment.py +++ b/examples/remarketing/upload_conversion_adjustment.py @@ -96,7 +96,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Uploads a conversion adjustment." diff --git a/examples/remarketing/upload_conversion_enhancement.py b/examples/remarketing/upload_conversion_enhancement.py index 58d13ec9d..f6a035eeb 100644 --- a/examples/remarketing/upload_conversion_enhancement.py +++ b/examples/remarketing/upload_conversion_enhancement.py @@ -209,7 +209,7 @@ def normalize_and_hash(s): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Imports offline call conversion values for calls related " diff --git a/examples/remarketing/upload_conversion_with_identifiers.py b/examples/remarketing/upload_conversion_with_identifiers.py index 94725c6e8..887e4f2a7 100644 --- a/examples/remarketing/upload_conversion_with_identifiers.py +++ b/examples/remarketing/upload_conversion_with_identifiers.py @@ -161,7 +161,7 @@ def normalize_and_hash(s): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Imports offline call conversion values for calls related " diff --git a/examples/remarketing/upload_offline_conversion.py b/examples/remarketing/upload_offline_conversion.py index a5112431a..d4a3ddf3e 100644 --- a/examples/remarketing/upload_offline_conversion.py +++ b/examples/remarketing/upload_offline_conversion.py @@ -112,7 +112,7 @@ def main( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Uploads an offline conversion." diff --git a/examples/remarketing/upload_store_sales_transactions.py b/examples/remarketing/upload_store_sales_transactions.py index e22f1698d..73b3a5eab 100644 --- a/examples/remarketing/upload_store_sales_transactions.py +++ b/examples/remarketing/upload_store_sales_transactions.py @@ -436,9 +436,7 @@ def build_offline_user_data_job_operations( address_identifier.address_info.hashed_first_name = normalize_and_hash( "John" ) - address_identifier.address_info.hashed_last_name = normalize_and_hash( - "Doe" - ) + address_identifier.address_info.hashed_last_name = normalize_and_hash("Doe") # Country and zip codes are sent in plain text. address_identifier.address_info.country_code = "US" address_identifier.address_info.postal_code = "10011" @@ -567,7 +565,7 @@ def check_job_status(client, customer_id, offline_user_data_job_resource_name): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="This example uploads offline data for store sales " diff --git a/examples/reporting/get_hotel_ads_performance.py b/examples/reporting/get_hotel_ads_performance.py index 9283e6084..1a1f09b4d 100755 --- a/examples/reporting/get_hotel_ads_performance.py +++ b/examples/reporting/get_hotel_ads_performance.py @@ -78,7 +78,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Retrieves Hotel-ads performance statistics.") diff --git a/examples/reporting/get_keyword_stats.py b/examples/reporting/get_keyword_stats.py index 297e74019..7d4f0b528 100755 --- a/examples/reporting/get_keyword_stats.py +++ b/examples/reporting/get_keyword_stats.py @@ -77,7 +77,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Retrieves a campaign's negative keywords.") diff --git a/examples/reporting/parallel_report_download.py b/examples/reporting/parallel_report_download.py index f51bd0b14..fbb656026 100644 --- a/examples/reporting/parallel_report_download.py +++ b/examples/reporting/parallel_report_download.py @@ -175,7 +175,7 @@ def generate_inputs(client, customer_ids, queries): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Download a set of reports in parallel from a list of " diff --git a/examples/shopping_ads/add_listing_scope.py b/examples/shopping_ads/add_listing_scope.py index 992138742..ecea992a3 100755 --- a/examples/shopping_ads/add_listing_scope.py +++ b/examples/shopping_ads/add_listing_scope.py @@ -96,7 +96,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Adds a shopping listing scope to a shopping campaign.") diff --git a/examples/shopping_ads/add_performance_max_product_listing_group_tree.py b/examples/shopping_ads/add_performance_max_product_listing_group_tree.py index c5ec3bd3c..81950c373 100644 --- a/examples/shopping_ads/add_performance_max_product_listing_group_tree.py +++ b/examples/shopping_ads/add_performance_max_product_listing_group_tree.py @@ -189,11 +189,15 @@ def create_root(self): mutate_operation.asset_group_listing_group_filter_operation.create ) - asset_group_listing_group_filter.resource_name = googleads_service.asset_group_listing_group_filter_path( - self.customer_id, self.asset_group_id, self.root_listing_id + asset_group_listing_group_filter.resource_name = ( + googleads_service.asset_group_listing_group_filter_path( + self.customer_id, self.asset_group_id, self.root_listing_id + ) ) - asset_group_listing_group_filter.asset_group = googleads_service.asset_group_path( - self.customer_id, self.asset_group_id + asset_group_listing_group_filter.asset_group = ( + googleads_service.asset_group_path( + self.customer_id, self.asset_group_id + ) ) # Since this is the root node, do not set the # parent_listing_group_filter field. For all other nodes, this would @@ -239,14 +243,20 @@ def create_subdivision(self, parent_id, temporary_id, dimension): mutate_operation.asset_group_listing_group_filter_operation.create ) - asset_group_listing_group_filter.resource_name = googleads_service.asset_group_listing_group_filter_path( - self.customer_id, self.asset_group_id, temporary_id + asset_group_listing_group_filter.resource_name = ( + googleads_service.asset_group_listing_group_filter_path( + self.customer_id, self.asset_group_id, temporary_id + ) ) - asset_group_listing_group_filter.asset_group = googleads_service.asset_group_path( - self.customer_id, self.asset_group_id + asset_group_listing_group_filter.asset_group = ( + googleads_service.asset_group_path( + self.customer_id, self.asset_group_id + ) ) - asset_group_listing_group_filter.parent_listing_group_filter = googleads_service.asset_group_listing_group_filter_path( - self.customer_id, self.asset_group_id, parent_id + asset_group_listing_group_filter.parent_listing_group_filter = ( + googleads_service.asset_group_listing_group_filter_path( + self.customer_id, self.asset_group_id, parent_id + ) ) asset_group_listing_group_filter.type_ = ( self.client.enums.ListingGroupFilterTypeEnum.SUBDIVISION @@ -281,14 +291,20 @@ def create_unit(self, parent_id, temporary_id, dimension): mutate_operation.asset_group_listing_group_filter_operation.create ) - asset_group_listing_group_filter.resource_name = googleads_service.asset_group_listing_group_filter_path( - self.customer_id, self.asset_group_id, temporary_id + asset_group_listing_group_filter.resource_name = ( + googleads_service.asset_group_listing_group_filter_path( + self.customer_id, self.asset_group_id, temporary_id + ) ) - asset_group_listing_group_filter.asset_group = googleads_service.asset_group_path( - self.customer_id, self.asset_group_id + asset_group_listing_group_filter.asset_group = ( + googleads_service.asset_group_path( + self.customer_id, self.asset_group_id + ) ) - asset_group_listing_group_filter.parent_listing_group_filter = googleads_service.asset_group_listing_group_filter_path( - self.customer_id, self.asset_group_id, parent_id + asset_group_listing_group_filter.parent_listing_group_filter = ( + googleads_service.asset_group_listing_group_filter_path( + self.customer_id, self.asset_group_id, parent_id + ) ) # We must use the UnitIncluded type to indicate that the # AssetGroupListingGroupFilter won't have children. @@ -325,20 +341,29 @@ def main(client, customer_id, asset_group_id, replace_existing_tree): if replace_existing_tree: # Retrieve a list of existing AssetGroupListingGroupFilters - existing_listing_group_filters = get_all_existing_listing_group_filter_assets_in_asset_group( - client, customer_id, asset_group_resource_name + existing_listing_group_filters = ( + get_all_existing_listing_group_filter_assets_in_asset_group( + client, customer_id, asset_group_resource_name + ) ) # If present, create MutateOperations to remove each # AssetGroupListingGroupFilter and add them to the list of operations. if existing_listing_group_filters: - remove_operation_factory = AssetGroupListingGroupFilterRemoveOperationFactory( - client, existing_listing_group_filters + remove_operation_factory = ( + AssetGroupListingGroupFilterRemoveOperationFactory( + client, existing_listing_group_filters + ) ) operations.extend(remove_operation_factory.remove_all()) - create_operation_factory = AssetGroupListingGroupFilterCreateOperationFactory( - client, customer_id, asset_group_id, _TEMPORARY_ID_LISTING_GROUP_ROOT, + create_operation_factory = ( + AssetGroupListingGroupFilterCreateOperationFactory( + client, + customer_id, + asset_group_id, + _TEMPORARY_ID_LISTING_GROUP_ROOT, + ) ) operations.append(create_operation_factory.create_root()) @@ -500,7 +525,7 @@ def print_response_details(mutate_operations, response): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/shopping_ads/add_performance_max_retail_campaign.py b/examples/shopping_ads/add_performance_max_retail_campaign.py index 828a25ca2..fe5683a06 100644 --- a/examples/shopping_ads/add_performance_max_retail_campaign.py +++ b/examples/shopping_ads/add_performance_max_retail_campaign.py @@ -66,7 +66,11 @@ # [START add_performance_max_retail_campaign] def main( - client, customer_id, merchant_center_account_id, sales_country, final_url, + client, + customer_id, + merchant_center_account_id, + sales_country, + final_url, ): """The main method that creates all necessary entities for the example. @@ -93,11 +97,22 @@ def main( # # Create the headlines. headline_asset_resource_names = create_multiple_text_assets( - client, customer_id, ["Travel", "Travel Reviews", "Book travel",], + client, + customer_id, + [ + "Travel", + "Travel Reviews", + "Book travel", + ], ) # Create the descriptions. description_asset_resource_names = create_multiple_text_assets( - client, customer_id, ["Take to the air!", "Fly to the sky!",], + client, + customer_id, + [ + "Take to the air!", + "Fly to the sky!", + ], ) # The below methods create and return MutateOperations that we later @@ -108,13 +123,20 @@ def main( # successfully or fail entirely, leaving no orphaned entities. See: # https://developers.google.com/google-ads/api/docs/mutating/overview campaign_budget_operation = create_campaign_budget_operation( - client, customer_id, + client, + customer_id, ) - performance_max_campaign_operation = create_performance_max_campaign_operation( - client, customer_id, merchant_center_account_id, sales_country, + performance_max_campaign_operation = ( + create_performance_max_campaign_operation( + client, + customer_id, + merchant_center_account_id, + sales_country, + ) ) campaign_criterion_operations = create_campaign_criterion_operations( - client, customer_id, + client, + customer_id, ) asset_group_operation = create_asset_group_operation( client, customer_id, final_url @@ -122,14 +144,18 @@ def main( listing_group_filter_operation = create_listing_group_filter_operation( client, customer_id ) - asset_and_asset_group_asset_operations = create_asset_and_asset_group_asset_operations( - client, - customer_id, - headline_asset_resource_names, - description_asset_resource_names, + asset_and_asset_group_asset_operations = ( + create_asset_and_asset_group_asset_operations( + client, + customer_id, + headline_asset_resource_names, + description_asset_resource_names, + ) ) conversion_goal_operations = create_conversion_goal_operations( - client, customer_id, customer_conversion_goals, + client, + customer_id, + customer_conversion_goals, ) # Send the operations in a single Mutate request. @@ -155,7 +181,8 @@ def main( # [START add_performance_max_retail_campaign_2] def create_campaign_budget_operation( - client, customer_id, + client, + customer_id, ): """Creates a MutateOperation that creates a new CampaignBudget. @@ -193,7 +220,10 @@ def create_campaign_budget_operation( # [START add_performance_max_retail_campaign_3] def create_performance_max_campaign_operation( - client, customer_id, merchant_center_account_id, sales_country, + client, + customer_id, + merchant_center_account_id, + sales_country, ): """Creates a MutateOperation that creates a new Performance Max campaign. @@ -274,7 +304,8 @@ def create_performance_max_campaign_operation( # [START add_performance_max_retail_campaign_4] def create_campaign_criterion_operations( - client, customer_id, + client, + customer_id, ): """Creates a list of MutateOperations that create new campaign criteria. @@ -303,8 +334,8 @@ def create_campaign_criterion_operations( ) # Adds one positive location target for New York City (ID=1023191), # specifically adding the positive criteria before the negative one. - campaign_criterion.location.geo_target_constant = geo_target_constant_service.geo_target_constant_path( - "1023191" + campaign_criterion.location.geo_target_constant = ( + geo_target_constant_service.geo_target_constant_path("1023191") ) campaign_criterion.negative = False operations.append(mutate_operation) @@ -315,8 +346,8 @@ def create_campaign_criterion_operations( campaign_criterion.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) - campaign_criterion.location.geo_target_constant = geo_target_constant_service.geo_target_constant_path( - "1022762" + campaign_criterion.location.geo_target_constant = ( + geo_target_constant_service.geo_target_constant_path("1022762") ) campaign_criterion.negative = True operations.append(mutate_operation) @@ -330,8 +361,8 @@ def create_campaign_criterion_operations( # Set the language. # For a list of all language codes, see: # https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-7 - campaign_criterion.language.language_constant = googleads_service.language_constant_path( - "1000" + campaign_criterion.language.language_constant = ( + googleads_service.language_constant_path("1000") ) # English operations.append(mutate_operation) @@ -368,7 +399,8 @@ def create_multiple_text_assets(client, customer_id, texts): # Send the operations in a single Mutate request. response = googleads_service.mutate( - customer_id=customer_id, mutate_operations=operations, + customer_id=customer_id, + mutate_operations=operations, ) asset_resource_names = [] for result in response.mutate_operation_responses: @@ -406,7 +438,8 @@ def create_asset_group_operation(client, customer_id, final_url): asset_group.final_mobile_urls.append(final_url) asset_group.status = client.enums.AssetGroupStatusEnum.PAUSED asset_group.resource_name = googleads_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) return mutate_operation @@ -435,7 +468,8 @@ def create_listing_group_filter_operation(client, customer_id): mutate_operation.asset_group_listing_group_filter_operation.create ) asset_group_listing_group.asset_group = googleads_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) asset_group_listing_group.type_ = ( client.enums.ListingGroupFilterTypeEnum.UNIT_INCLUDED @@ -495,7 +529,8 @@ def create_asset_and_asset_group_asset_operations( asset_group_asset = mutate_operation.asset_group_asset_operation.create asset_group_asset.field_type = client.enums.AssetFieldTypeEnum.HEADLINE asset_group_asset.asset_group = asset_group_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = resource_name operations.append(mutate_operation) @@ -508,7 +543,8 @@ def create_asset_and_asset_group_asset_operations( client.enums.AssetFieldTypeEnum.DESCRIPTION ) asset_group_asset.asset_group = asset_group_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = resource_name operations.append(mutate_operation) @@ -600,7 +636,8 @@ def create_and_link_text_asset(client, customer_id, text, field_type): asset_group_asset = mutate_operation.asset_group_asset_operation.create asset_group_asset.field_type = field_type asset_group_asset.asset_group = asset_group_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = asset_service.asset_path( customer_id, _next_temp_id @@ -650,7 +687,8 @@ def create_and_link_image_asset( asset_group_asset = mutate_operation.asset_group_asset_operation.create asset_group_asset.field_type = field_type asset_group_asset.asset_group = asset_group_service.asset_group_path( - customer_id, _ASSET_GROUP_TEMPORARY_ID, + customer_id, + _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = asset_service.asset_path( customer_id, _next_temp_id @@ -733,7 +771,9 @@ def get_customer_conversion_goals(client, customer_id): def create_conversion_goal_operations( - client, customer_id, customer_conversion_goals, + client, + customer_id, + customer_conversion_goals, ): """Creates a list of MutateOperations that override customer conversion goals. @@ -760,11 +800,13 @@ def create_conversion_goal_operations( mutate_operation.campaign_conversion_goal_operation.update ) - campaign_conversion_goal.resource_name = campaign_conversion_goal_service.campaign_conversion_goal_path( - customer_id, - _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID, - customer_conversion_goal["category"].name, - customer_conversion_goal["origin"].name, + campaign_conversion_goal.resource_name = ( + campaign_conversion_goal_service.campaign_conversion_goal_path( + customer_id, + _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID, + customer_conversion_goal["category"].name, + customer_conversion_goal["origin"].name, + ) ) # Change the biddability for the campaign conversion goal. # Set biddability to True for the desired (category, origin). @@ -839,7 +881,7 @@ def print_response_details(response): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=("Creates a Performance Max retail campaign.") diff --git a/examples/shopping_ads/add_shopping_product_ad.py b/examples/shopping_ads/add_shopping_product_ad.py index a537681f0..1abb28d46 100755 --- a/examples/shopping_ads/add_shopping_product_ad.py +++ b/examples/shopping_ads/add_shopping_product_ad.py @@ -254,7 +254,7 @@ def add_default_shopping_listing_group( if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/shopping_ads/add_shopping_product_listing_group_tree.py b/examples/shopping_ads/add_shopping_product_listing_group_tree.py index 1b8adc71c..79fe6948a 100644 --- a/examples/shopping_ads/add_shopping_product_listing_group_tree.py +++ b/examples/shopping_ads/add_shopping_product_listing_group_tree.py @@ -385,7 +385,7 @@ def create_listing_group_unit_biddable( if __name__ == "__main__": - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Add shopping product listing group tree to a shopping ad " diff --git a/examples/shopping_ads/add_shopping_smart_ad.py b/examples/shopping_ads/add_shopping_smart_ad.py deleted file mode 100644 index 02d346505..000000000 --- a/examples/shopping_ads/add_shopping_smart_ad.py +++ /dev/null @@ -1,377 +0,0 @@ -#!/usr/bin/env python -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Creates a smart shopping campaign, ad group, ad, and listing group. - -These will be created for "All products". - -Prerequisites: -- You need to have access to a Merchant Center account. You can find - instructions to create a Merchant Center account here: - https://support.google.com/merchants/answer/188924. - This account must be linked to your Google Ads account. The integration - instructions can be found at: - https://developers.google.com/google-ads/api/docs/shopping-ads/merchant-center -- You need your Google Ads account to track conversions. The different ways - to track conversions can be found here: - https://support.google.com/google-ads/answer/1722054. -""" - - -import argparse -import sys -from uuid import uuid4 - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException - - -def main( - client, - customer_id, - merchant_center_account_id, - create_default_listing_group, -): - """Creates a smart shopping campaign, ad group, ad, and listing group. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - merchant_center_account_id: The Merchant Center account ID. - create_default_listing_group: Boolean, whether to create a default - listing group. - """ - # Create a budget to be used by the campaign that will be created below. - budget_resource_name = add_campaign_budget(client, customer_id) - - # Create a smart shopping campaign. - campaign_resource_name = add_smart_shopping_campaign( - client, - customer_id, - budget_resource_name, - merchant_center_account_id, - ) - - # Create a smart shopping ad group. - ad_group_resource_name = add_smart_shopping_ad_group( - client, customer_id, campaign_resource_name - ) - - # Creates a smart shopping ad group ad. - add_smart_shopping_ad_group_ad(client, customer_id, ad_group_resource_name) - - if create_default_listing_group: - # A product group is a subset of inventory. Listing groups are the - # equivalent of product groups in the API and allow you to bid on - # the chosen group or exclude a group from bidding. - # This method creates an ad group criterion containing a listing - # group. - add_shopping_listing_group(client, customer_id, ad_group_resource_name) - - -def add_campaign_budget(client, customer_id): - """Creates a campaign budget in the specified client account. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - - Returns: - The string resource name of the newly created campaign budget. - """ - # Get the CampaignBudgetService client. - campaign_budget_service = client.get_service("CampaignBudgetService") - - # Create a campaign budget operation and configure the smart shopping - # campaign budget. - campaign_budget_operation = client.get_type("CampaignBudgetOperation") - campaign_budget = campaign_budget_operation.create - campaign_budget.name = f"Interplanetary Cruise Budget #{uuid4()}" - campaign_budget.delivery_method = ( - client.enums.BudgetDeliveryMethodEnum.STANDARD - ) - # The budget is specified in the local currency of the account. The amount - # should be specified in micros; one million is equivalent to one unit. - campaign_budget.amount_micros = 5000000 - # Budgets for smart shopping campaigns cannot be shared. - campaign_budget.explicitly_shared = False - - # Add the campaign budget, then print and return the resulting campaign - # budget's resource name. - campaign_budget_response = campaign_budget_service.mutate_campaign_budgets( - customer_id=customer_id, operations=[campaign_budget_operation] - ) - campaign_budget_resource_name = campaign_budget_response.results[ - 0 - ].resource_name - print( - "Added a smart shopping campaign budget with resource name: " - f"'{campaign_budget_resource_name}'." - ) - - return campaign_budget_resource_name - - -# [START add_shopping_smart_ad_3] -def add_smart_shopping_campaign( - client, customer_id, budget_resource_name, merchant_center_account_id -): - """Creates a new shopping campaign for smart shopping ads. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - budget_resource_name: The target campaign budget for the new campaign. - merchant_center_account_id: The Merchant Center account to which the - campaign will be linked. - - Returns: - The string resource name of the newly created ad group. - """ - # Get the CampaignService client. - campaign_service = client.get_service("CampaignService") - - # [START add_shopping_smart_ad] - # Create a campaign operation and configure the smart shopping campaign. - campaign_operation = client.get_type("CampaignOperation") - campaign = campaign_operation.create - campaign.name = f"Interplanetary Cruise Campaign #{uuid4()}" - campaign.campaign_budget = budget_resource_name - # Configure settings related to shopping campaigns including advertising - # channel type, advertising channel sub-type and shopping setting. - campaign.advertising_channel_type = ( - client.enums.AdvertisingChannelTypeEnum.SHOPPING - ) - campaign.advertising_channel_sub_type = ( - client.enums.AdvertisingChannelSubTypeEnum.SHOPPING_SMART_ADS - ) - campaign.shopping_setting.merchant_id = merchant_center_account_id - # Set the sales country of products to include in the campaign. - # Only products from Merchant Center targeting this country will - # appear in the campaign. - campaign.shopping_setting.sales_country = "US" - # Recommendation: Set the campaign to PAUSED when creating it to prevent - # the ads from immediately serving. Set to ENABLED once you've added - # targeting and the ads are ready to serve. - campaign.status = client.enums.CampaignStatusEnum.PAUSED - # Bidding strategy must be set directly on the campaign. - # Setting a portfolio bidding strategy by resource name is not supported. - # Maximize conversion value is the only strategy supported for smart - # shopping campaigns. An optional ROAS (Return on Advertising Spend) can be - # set for maximize_conversion_value. The ROAS value must be specified as a - # ratio in the API. It is calculated by dividing "total value" by - # "total spend". For more information on maximize conversion value, see the - # support article: http://support.google.com/google-ads/answer/7684216. - campaign.maximize_conversion_value.target_roas = 3.5 - # [END add_shopping_smart_ad] - - # Add the campaign, then print and return the resulting campaign's resource - # name. - campaign_response = campaign_service.mutate_campaigns( - customer_id=customer_id, operations=[campaign_operation] - ) - campaign_resource_name = campaign_response.results[0].resource_name - print( - "Added a smart shopping campaign with resource name: " - f"'{campaign_resource_name}'." - ) - - return campaign_resource_name - # [END add_shopping_smart_ad_3] - - -# [START add_shopping_smart_ad_2] -def add_smart_shopping_ad_group(client, customer_id, campaign_resource_name): - """Creates a new ad group in the specified smart shopping campaign. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - campaign_resource_name: The target campaign for the new ad group. - - Returns: - The string resource name of the newly created ad group. - """ - # Get the AdGroupCriterionService client. - ad_group_service = client.get_service("AdGroupService") - - # Create an ad group operation and configure the new ad group. - ad_group_operation = client.get_type("AdGroupOperation") - ad_group = ad_group_operation.create - ad_group.name = f"Earth to Mars Cruises #{uuid4()}" - ad_group.campaign = campaign_resource_name - # Set the ad group type to SHOPPING_SMART_ADS. - ad_group.type_ = client.enums.AdGroupTypeEnum.SHOPPING_SMART_ADS - ad_group.status = client.enums.AdGroupStatusEnum.ENABLED - - # Add the ad group, then print and return the resulting ad group's resource - # name. - ad_group_response = ad_group_service.mutate_ad_groups( - customer_id=customer_id, operations=[ad_group_operation] - ) - ad_group_resource_name = ad_group_response.results[0].resource_name - print( - "Added a smart shopping ad group with resource name: " - f"'{ad_group_resource_name}'." - ) - - return ad_group_resource_name - # [END add_shopping_smart_ad_2] - - -# [START add_shopping_smart_ad_1] -def add_smart_shopping_ad_group_ad( - client, customer_id, ad_group_resource_name -): - """Creates a new ad group ad in the specified smart shopping ad group. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - ad_group_resource_name: The target ad group for the new listing group. - - Returns: - The string resource name of the newly created ad group ad. - """ - # Get the AdGroupCriterionService client. - ad_group_ad_service = client.get_service("AdGroupAdService") - - # Create an ad group ad operation and configure the ad group ad. - ad_group_ad_operation = client.get_type("AdGroupAdOperation") - ad_group_ad = ad_group_ad_operation.create - # Set the ad group. - ad_group_ad.ad_group = ad_group_resource_name - # Set a new smart shopping ad. - client.copy_from( - ad_group_ad.ad.shopping_smart_ad, client.get_type("ShoppingSmartAdInfo") - ) - ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED - - # Add the ad group ad, then print and return the resulting ad group ad's - # resource name. - ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads( - customer_id=customer_id, operations=[ad_group_ad_operation] - ) - ad_group_ad_resource_name = ad_group_ad_response.results[0].resource_name - print( - "Added a smart shopping ad group ad with resource name: " - f"'{ad_group_ad_resource_name}'." - ) - - return ad_group_ad_resource_name - # [END add_shopping_smart_ad_1] - - -def add_shopping_listing_group(client, customer_id, ad_group_resource_name): - """Creates a new shopping listing group for the specified ad group. - - This is known as a "product group" in the Google Ads user interface. The - listing group will be added to the ad group using an "ad group criterion". - See the Google Ads API Shopping guide for more information on listing groups: - https://developers.google.com/google-ads/api/docs/shopping-ads/overview. - - Args: - client: An initialized Google Ads client. - customer_id: The Google Ads customer ID. - ad_group_resource_name: The target ad group for the new listing group. - - Returns: - The string resource name of the newly created ad group criterion. - """ - # Get the AdGroupCriterionService client. - ad_group_criterion_service = client.get_service("AdGroupCriterionService") - - # Creates a new ad group criterion. This will contain a listing group. - # This will be the listing group for 'All products' and will contain a - # single root node. - ad_group_criterion_operation = client.get_type("AdGroupCriterionOperation") - ad_group_criterion = ad_group_criterion_operation.create - ad_group_criterion.ad_group = ad_group_resource_name - ad_group_criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED - ad_group_criterion.listing_group.type_ = ( - client.enums.ListingGroupTypeEnum.UNIT - ) - - # Ad the listing group criterion, then display and return the resulting - # ad group criterion's resource name. - ad_group_criterion_response = ( - ad_group_criterion_service.mutate_ad_group_criteria( - customer_id=customer_id, operations=[ad_group_criterion_operation] - ) - ) - ad_group_criterion_resource_name = ad_group_criterion_response.results[ - 0 - ].resource_name - print( - "Added an ad group criterion containing a listing group with resource " - f"name: '{ad_group_criterion_resource_name}'." - ) - - return ad_group_criterion_resource_name - - -if __name__ == "__main__": - # GoogleAdsClient will read the google-ads.yaml configuration file in the - # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") - - parser = argparse.ArgumentParser( - description=( - "Creates a smart shopping campaign, ad group, ad, and listing " - "group for 'All products'." - ) - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - parser.add_argument( - "-m", - "--merchant_center_account_id", - type=int, - required=True, - help="The Merchant Center account ID.", - ) - parser.add_argument( - "-d", - "--create_default_listing_group", - action="store_true", - default=False, - help="Optional, whether to create a default listing group. " - "Default is false.", - ) - args = parser.parse_args() - - try: - main( - googleads_client, - args.customer_id, - args.merchant_center_account_id, - args.create_default_listing_group, - ) - except GoogleAdsException as ex: - print( - f"Request with ID '{ex.request_id}' failed with status " - f"'{ex.error.code().name}' and includes the following errors:" - ) - for error in ex.failure.errors: - print(f"\tError with message '{error.message}'.") - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) diff --git a/examples/shopping_ads/get_product_bidding_category_constant.py b/examples/shopping_ads/get_product_bidding_category_constant.py index 163b660bc..7189c9a79 100755 --- a/examples/shopping_ads/get_product_bidding_category_constant.py +++ b/examples/shopping_ads/get_product_bidding_category_constant.py @@ -94,7 +94,7 @@ def __init__(self, name=None, category_id=None, children=None): if __name__ == "__main__": - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description="Get Product Bidding Category Constant" diff --git a/examples/targeting/add_campaign_targeting_criteria.py b/examples/targeting/add_campaign_targeting_criteria.py index b308c850b..e4aefad20 100755 --- a/examples/targeting/add_campaign_targeting_criteria.py +++ b/examples/targeting/add_campaign_targeting_criteria.py @@ -111,7 +111,7 @@ def create_proximity_op(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/targeting/add_customer_negative_criteria.py b/examples/targeting/add_customer_negative_criteria.py index 1c0e7a889..2b1f0bee1 100755 --- a/examples/targeting/add_customer_negative_criteria.py +++ b/examples/targeting/add_customer_negative_criteria.py @@ -67,7 +67,7 @@ def main(client, customer_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/targeting/add_demographic_targeting_criteria.py b/examples/targeting/add_demographic_targeting_criteria.py index ebf383926..e34c59a0c 100755 --- a/examples/targeting/add_demographic_targeting_criteria.py +++ b/examples/targeting/add_demographic_targeting_criteria.py @@ -68,7 +68,7 @@ def main(client, customer_id, ad_group_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/targeting/get_campaign_targeting_criteria.py b/examples/targeting/get_campaign_targeting_criteria.py index 32070120c..b298e8db6 100755 --- a/examples/targeting/get_campaign_targeting_criteria.py +++ b/examples/targeting/get_campaign_targeting_criteria.py @@ -65,7 +65,7 @@ def main(client, customer_id, campaign_id): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/examples/targeting/get_geo_target_constants_by_names.py b/examples/targeting/get_geo_target_constants_by_names.py index 4a05cdd35..91c4f084f 100755 --- a/examples/targeting/get_geo_target_constants_by_names.py +++ b/examples/targeting/get_geo_target_constants_by_names.py @@ -64,7 +64,7 @@ def main(client): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") try: main(googleads_client) diff --git a/examples/targeting/search_for_language_and_carrier_constants.py b/examples/targeting/search_for_language_and_carrier_constants.py index e2bac1029..1d95c166e 100644 --- a/examples/targeting/search_for_language_and_carrier_constants.py +++ b/examples/targeting/search_for_language_and_carrier_constants.py @@ -122,7 +122,7 @@ def search_for_carrier_constants(client, customer_id, carrier_country_code): if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v11") + googleads_client = GoogleAdsClient.load_from_storage(version="v12") parser = argparse.ArgumentParser( description=( diff --git a/google/ads/googleads/client.py b/google/ads/googleads/client.py index bcd4d34c2..a954f98b8 100644 --- a/google/ads/googleads/client.py +++ b/google/ads/googleads/client.py @@ -33,7 +33,7 @@ _SERVICE_CLIENT_TEMPLATE = "{}Client" -_VALID_API_VERSIONS = ["v11", "v10"] +_VALID_API_VERSIONS = ["v12", "v11", "v10"] _DEFAULT_VERSION = _VALID_API_VERSIONS[0] # Retrieve the version of this client library to be sent in the user-agent diff --git a/google/ads/googleads/v12/__init__.py b/google/ads/googleads/v12/__init__.py new file mode 100644 index 000000000..d84d55991 --- /dev/null +++ b/google/ads/googleads/v12/__init__.py @@ -0,0 +1,1805 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import importlib +import sys + + +if sys.version_info < (3, 7): + raise ImportError("This module requires Python 3.7 or later.") + + +_lazy_type_to_package_map = { + # Message types + "AdAssetPolicySummary": "google.ads.googleads.v12.common.types.asset_policy", + "AdDiscoveryCarouselCardAsset": "google.ads.googleads.v12.common.types.ad_asset", + "AddressInfo": "google.ads.googleads.v12.common.types.criteria", + "AdImageAsset": "google.ads.googleads.v12.common.types.ad_asset", + "AdMediaBundleAsset": "google.ads.googleads.v12.common.types.ad_asset", + "AdScheduleInfo": "google.ads.googleads.v12.common.types.criteria", + "AdTextAsset": "google.ads.googleads.v12.common.types.ad_asset", + "AdVideoAsset": "google.ads.googleads.v12.common.types.ad_asset", + "AffiliateLocationFeedItem": "google.ads.googleads.v12.common.types.extensions", + "AgeDimension": "google.ads.googleads.v12.common.types.audiences", + "AgeRangeInfo": "google.ads.googleads.v12.common.types.criteria", + "AgeSegment": "google.ads.googleads.v12.common.types.audiences", + "AppAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "AppEngagementAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "AppFeedItem": "google.ads.googleads.v12.common.types.extensions", + "AppPaymentModelInfo": "google.ads.googleads.v12.common.types.criteria", + "AppPreRegistrationAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "AssetInteractionTarget": "google.ads.googleads.v12.common.types.segments", + "AssetUsage": "google.ads.googleads.v12.common.types.asset_usage", + "AudienceDimension": "google.ads.googleads.v12.common.types.audiences", + "AudienceExclusionDimension": "google.ads.googleads.v12.common.types.audiences", + "AudienceInfo": "google.ads.googleads.v12.common.types.criteria", + "AudienceSegment": "google.ads.googleads.v12.common.types.audiences", + "AudienceSegmentDimension": "google.ads.googleads.v12.common.types.audiences", + "BasicUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "BidModifierSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "BidModifierSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "BookOnGoogleAsset": "google.ads.googleads.v12.common.types.asset_types", + "BudgetCampaignAssociationStatus": "google.ads.googleads.v12.common.types.segments", + "BudgetSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "BudgetSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "BusinessNameFilter": "google.ads.googleads.v12.common.types.feed_item_set_filter_type_infos", + "BusinessProfileBusinessNameFilter": "google.ads.googleads.v12.common.types.asset_set_types", + "BusinessProfileLocation": "google.ads.googleads.v12.common.types.asset_types", + "BusinessProfileLocationGroup": "google.ads.googleads.v12.common.types.asset_set_types", + "BusinessProfileLocationSet": "google.ads.googleads.v12.common.types.asset_set_types", + "CallAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "CallAsset": "google.ads.googleads.v12.common.types.asset_types", + "CallFeedItem": "google.ads.googleads.v12.common.types.extensions", + "CalloutAsset": "google.ads.googleads.v12.common.types.asset_types", + "CalloutFeedItem": "google.ads.googleads.v12.common.types.extensions", + "CallToActionAsset": "google.ads.googleads.v12.common.types.asset_types", + "CarrierInfo": "google.ads.googleads.v12.common.types.criteria", + "ChainFilter": "google.ads.googleads.v12.common.types.asset_set_types", + "ChainLocationGroup": "google.ads.googleads.v12.common.types.asset_set_types", + "ChainSet": "google.ads.googleads.v12.common.types.asset_set_types", + "ClickLocation": "google.ads.googleads.v12.common.types.click_location", + "CombinedAudienceInfo": "google.ads.googleads.v12.common.types.criteria", + "CombinedRuleUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "Commission": "google.ads.googleads.v12.common.types.bidding", + "ConceptGroup": "google.ads.googleads.v12.common.types.keyword_plan_common", + "ContentLabelInfo": "google.ads.googleads.v12.common.types.criteria", + "CpcBidSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "CpcBidSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "CpvBidSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "CpvBidSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "CriterionCategoryAvailability": "google.ads.googleads.v12.common.types.criterion_category_availability", + "CriterionCategoryChannelAvailability": "google.ads.googleads.v12.common.types.criterion_category_availability", + "CriterionCategoryLocaleAvailability": "google.ads.googleads.v12.common.types.criterion_category_availability", + "CrmBasedUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "CustomAffinityInfo": "google.ads.googleads.v12.common.types.criteria", + "CustomAudienceInfo": "google.ads.googleads.v12.common.types.criteria", + "CustomAudienceSegment": "google.ads.googleads.v12.common.types.audiences", + "CustomerMatchUserListMetadata": "google.ads.googleads.v12.common.types.offline_user_data", + "CustomIntentInfo": "google.ads.googleads.v12.common.types.criteria", + "CustomizerValue": "google.ads.googleads.v12.common.types.customizer_value", + "CustomParameter": "google.ads.googleads.v12.common.types.custom_parameter", + "DateRange": "google.ads.googleads.v12.common.types.dates", + "DetailedDemographicSegment": "google.ads.googleads.v12.common.types.audiences", + "DeviceInfo": "google.ads.googleads.v12.common.types.criteria", + "DiscoveryCarouselAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "DiscoveryCarouselCardAsset": "google.ads.googleads.v12.common.types.asset_types", + "DiscoveryMultiAssetAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "DisplayUploadAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "DynamicAffiliateLocationSetFilter": "google.ads.googleads.v12.common.types.feed_item_set_filter_type_infos", + "DynamicBusinessProfileLocationGroupFilter": "google.ads.googleads.v12.common.types.asset_set_types", + "DynamicCustomAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicEducationAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicFlightsAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicHotelsAndRentalsAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicJobsAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicLocalAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicLocationSetFilter": "google.ads.googleads.v12.common.types.feed_item_set_filter_type_infos", + "DynamicRealEstateAsset": "google.ads.googleads.v12.common.types.asset_types", + "DynamicTravelAsset": "google.ads.googleads.v12.common.types.asset_types", + "EnhancedCpc": "google.ads.googleads.v12.common.types.bidding", + "EventAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "EventItemAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "ExclusionSegment": "google.ads.googleads.v12.common.types.audiences", + "ExpandedDynamicSearchAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ExpandedTextAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ExplorerAutoOptimizerSetting": "google.ads.googleads.v12.common.types.explorer_auto_optimizer_setting", + "ExpressionRuleUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "FinalAppUrl": "google.ads.googleads.v12.common.types.final_app_url", + "FlexibleRuleOperandInfo": "google.ads.googleads.v12.common.types.user_lists", + "FlexibleRuleUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "FrequencyCapEntry": "google.ads.googleads.v12.common.types.frequency_cap", + "FrequencyCapKey": "google.ads.googleads.v12.common.types.frequency_cap", + "GenderDimension": "google.ads.googleads.v12.common.types.audiences", + "GenderInfo": "google.ads.googleads.v12.common.types.criteria", + "GeoPointInfo": "google.ads.googleads.v12.common.types.criteria", + "HistoricalMetricsOptions": "google.ads.googleads.v12.common.types.keyword_plan_common", + "HotelAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "HotelAdvanceBookingWindowInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelCalloutAsset": "google.ads.googleads.v12.common.types.asset_types", + "HotelCalloutFeedItem": "google.ads.googleads.v12.common.types.extensions", + "HotelCheckInDateRangeInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelCheckInDayInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelCityInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelClassInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelCountryRegionInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelDateSelectionTypeInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelIdInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelLengthOfStayInfo": "google.ads.googleads.v12.common.types.criteria", + "HotelStateInfo": "google.ads.googleads.v12.common.types.criteria", + "HouseholdIncomeDimension": "google.ads.googleads.v12.common.types.audiences", + "ImageAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ImageAsset": "google.ads.googleads.v12.common.types.asset_types", + "ImageDimension": "google.ads.googleads.v12.common.types.asset_types", + "ImageFeedItem": "google.ads.googleads.v12.common.types.extensions", + "IncomeRangeInfo": "google.ads.googleads.v12.common.types.criteria", + "InFeedVideoAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "InteractionTypeInfo": "google.ads.googleads.v12.common.types.criteria", + "IpBlockInfo": "google.ads.googleads.v12.common.types.criteria", + "ItemAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "Keyword": "google.ads.googleads.v12.common.types.segments", + "KeywordAnnotations": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordConcept": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordInfo": "google.ads.googleads.v12.common.types.criteria", + "KeywordPlanAggregateMetricResults": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordPlanAggregateMetrics": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordPlanDeviceSearches": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordPlanHistoricalMetrics": "google.ads.googleads.v12.common.types.keyword_plan_common", + "KeywordThemeInfo": "google.ads.googleads.v12.common.types.criteria", + "LanguageInfo": "google.ads.googleads.v12.common.types.criteria", + "LeadFormAsset": "google.ads.googleads.v12.common.types.asset_types", + "LeadFormCustomQuestionField": "google.ads.googleads.v12.common.types.asset_types", + "LeadFormDeliveryMethod": "google.ads.googleads.v12.common.types.asset_types", + "LeadFormField": "google.ads.googleads.v12.common.types.asset_types", + "LeadFormSingleChoiceAnswers": "google.ads.googleads.v12.common.types.asset_types", + "LegacyAppInstallAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "LegacyResponsiveDisplayAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "LifeEventSegment": "google.ads.googleads.v12.common.types.audiences", + "ListingDimensionInfo": "google.ads.googleads.v12.common.types.criteria", + "ListingGroupInfo": "google.ads.googleads.v12.common.types.criteria", + "ListingScopeInfo": "google.ads.googleads.v12.common.types.criteria", + "LocalAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "LocationAsset": "google.ads.googleads.v12.common.types.asset_types", + "LocationFeedItem": "google.ads.googleads.v12.common.types.extensions", + "LocationGroupInfo": "google.ads.googleads.v12.common.types.criteria", + "LocationInfo": "google.ads.googleads.v12.common.types.criteria", + "LocationSet": "google.ads.googleads.v12.common.types.asset_set_types", + "LogicalUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "LogicalUserListOperandInfo": "google.ads.googleads.v12.common.types.user_lists", + "ManualCpa": "google.ads.googleads.v12.common.types.bidding", + "ManualCpc": "google.ads.googleads.v12.common.types.bidding", + "ManualCpm": "google.ads.googleads.v12.common.types.bidding", + "ManualCpv": "google.ads.googleads.v12.common.types.bidding", + "MapsLocationInfo": "google.ads.googleads.v12.common.types.asset_set_types", + "MapsLocationSet": "google.ads.googleads.v12.common.types.asset_set_types", + "MatchingFunction": "google.ads.googleads.v12.common.types.matching_function", + "MaximizeConversions": "google.ads.googleads.v12.common.types.bidding", + "MaximizeConversionValue": "google.ads.googleads.v12.common.types.bidding", + "MediaBundleAsset": "google.ads.googleads.v12.common.types.asset_types", + "MetricGoal": "google.ads.googleads.v12.common.types.metric_goal", + "Metrics": "google.ads.googleads.v12.common.types.metrics", + "MobileAppAsset": "google.ads.googleads.v12.common.types.asset_types", + "MobileAppCategoryInfo": "google.ads.googleads.v12.common.types.criteria", + "MobileApplicationInfo": "google.ads.googleads.v12.common.types.criteria", + "MobileDeviceInfo": "google.ads.googleads.v12.common.types.criteria", + "Money": "google.ads.googleads.v12.common.types.feed_common", + "MonthlySearchVolume": "google.ads.googleads.v12.common.types.keyword_plan_common", + "OfflineUserAddressInfo": "google.ads.googleads.v12.common.types.offline_user_data", + "Operand": "google.ads.googleads.v12.common.types.matching_function", + "OperatingSystemVersionInfo": "google.ads.googleads.v12.common.types.criteria", + "PageFeedAsset": "google.ads.googleads.v12.common.types.asset_types", + "ParentalStatusDimension": "google.ads.googleads.v12.common.types.audiences", + "ParentalStatusInfo": "google.ads.googleads.v12.common.types.criteria", + "PercentCpc": "google.ads.googleads.v12.common.types.bidding", + "PercentCpcBidSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "PercentCpcBidSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "PlacementInfo": "google.ads.googleads.v12.common.types.criteria", + "PolicySummary": "google.ads.googleads.v12.common.types.policy_summary", + "PolicyTopicConstraint": "google.ads.googleads.v12.common.types.policy", + "PolicyTopicEntry": "google.ads.googleads.v12.common.types.policy", + "PolicyTopicEvidence": "google.ads.googleads.v12.common.types.policy", + "PolicyValidationParameter": "google.ads.googleads.v12.common.types.policy", + "PolicyViolationKey": "google.ads.googleads.v12.common.types.policy", + "PreferredContentInfo": "google.ads.googleads.v12.common.types.criteria", + "PriceAsset": "google.ads.googleads.v12.common.types.asset_types", + "PriceFeedItem": "google.ads.googleads.v12.common.types.extensions", + "PriceOffer": "google.ads.googleads.v12.common.types.extensions", + "PriceOffering": "google.ads.googleads.v12.common.types.asset_types", + "ProductBiddingCategoryInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductBrandInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductChannelExclusivityInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductChannelInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductConditionInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductCustomAttributeInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductGroupingInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductItemIdInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductLabelsInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductLegacyConditionInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductTypeFullInfo": "google.ads.googleads.v12.common.types.criteria", + "ProductTypeInfo": "google.ads.googleads.v12.common.types.criteria", + "PromotionAsset": "google.ads.googleads.v12.common.types.asset_types", + "PromotionFeedItem": "google.ads.googleads.v12.common.types.extensions", + "ProximityInfo": "google.ads.googleads.v12.common.types.criteria", + "RealTimeBiddingSetting": "google.ads.googleads.v12.common.types.real_time_bidding_setting", + "ResponsiveDisplayAdControlSpec": "google.ads.googleads.v12.common.types.ad_type_infos", + "ResponsiveDisplayAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ResponsiveSearchAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "RuleBasedUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "Segments": "google.ads.googleads.v12.common.types.segments", + "ShoppingComparisonListingAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ShoppingLoyalty": "google.ads.googleads.v12.common.types.offline_user_data", + "ShoppingProductAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "ShoppingSmartAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "SimilarUserListInfo": "google.ads.googleads.v12.common.types.user_lists", + "SitelinkAsset": "google.ads.googleads.v12.common.types.asset_types", + "SitelinkFeedItem": "google.ads.googleads.v12.common.types.extensions", + "SkAdNetworkSourceApp": "google.ads.googleads.v12.common.types.segments", + "SmartCampaignAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "StoreAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "StoreSalesMetadata": "google.ads.googleads.v12.common.types.offline_user_data", + "StoreSalesThirdPartyMetadata": "google.ads.googleads.v12.common.types.offline_user_data", + "StructuredSnippetAsset": "google.ads.googleads.v12.common.types.asset_types", + "StructuredSnippetFeedItem": "google.ads.googleads.v12.common.types.extensions", + "TagSnippet": "google.ads.googleads.v12.common.types.tag_snippet", + "TargetCpa": "google.ads.googleads.v12.common.types.bidding", + "TargetCpaSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "TargetCpaSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "TargetCpm": "google.ads.googleads.v12.common.types.bidding", + "TargetImpressionShare": "google.ads.googleads.v12.common.types.bidding", + "TargetImpressionShareSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "TargetImpressionShareSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "TargetingSetting": "google.ads.googleads.v12.common.types.targeting_setting", + "TargetRestriction": "google.ads.googleads.v12.common.types.targeting_setting", + "TargetRestrictionOperation": "google.ads.googleads.v12.common.types.targeting_setting", + "TargetRoas": "google.ads.googleads.v12.common.types.bidding", + "TargetRoasSimulationPoint": "google.ads.googleads.v12.common.types.simulation", + "TargetRoasSimulationPointList": "google.ads.googleads.v12.common.types.simulation", + "TargetSpend": "google.ads.googleads.v12.common.types.bidding", + "TextAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "TextAsset": "google.ads.googleads.v12.common.types.asset_types", + "TextLabel": "google.ads.googleads.v12.common.types.text_label", + "TextMessageFeedItem": "google.ads.googleads.v12.common.types.extensions", + "TopicInfo": "google.ads.googleads.v12.common.types.criteria", + "TransactionAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "UnknownListingDimensionInfo": "google.ads.googleads.v12.common.types.criteria", + "UrlCollection": "google.ads.googleads.v12.common.types.url_collection", + "UserAttribute": "google.ads.googleads.v12.common.types.offline_user_data", + "UserData": "google.ads.googleads.v12.common.types.offline_user_data", + "UserIdentifier": "google.ads.googleads.v12.common.types.offline_user_data", + "UserInterestInfo": "google.ads.googleads.v12.common.types.criteria", + "UserInterestSegment": "google.ads.googleads.v12.common.types.audiences", + "UserListActionInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListDateRuleItemInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListInfo": "google.ads.googleads.v12.common.types.criteria", + "UserListLogicalRuleInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListNumberRuleItemInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListRuleInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListRuleItemGroupInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListRuleItemInfo": "google.ads.googleads.v12.common.types.user_lists", + "UserListSegment": "google.ads.googleads.v12.common.types.audiences", + "UserListStringRuleItemInfo": "google.ads.googleads.v12.common.types.user_lists", + "Value": "google.ads.googleads.v12.common.types.value", + "VideoAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "VideoBumperInStreamAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "VideoNonSkippableInStreamAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "VideoOutstreamAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "VideoResponsiveAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "VideoTrueViewInStreamAdInfo": "google.ads.googleads.v12.common.types.ad_type_infos", + "WebhookDelivery": "google.ads.googleads.v12.common.types.asset_types", + "WebpageConditionInfo": "google.ads.googleads.v12.common.types.criteria", + "WebpageInfo": "google.ads.googleads.v12.common.types.criteria", + "WebpageSampleInfo": "google.ads.googleads.v12.common.types.criteria", + "YearMonth": "google.ads.googleads.v12.common.types.dates", + "YearMonthRange": "google.ads.googleads.v12.common.types.dates", + "YouTubeChannelInfo": "google.ads.googleads.v12.common.types.criteria", + "YoutubeVideoAsset": "google.ads.googleads.v12.common.types.asset_types", + "YouTubeVideoInfo": "google.ads.googleads.v12.common.types.criteria", + "AccessInvitationStatusEnum": "google.ads.googleads.v12.enums.types.access_invitation_status", + "AccessReasonEnum": "google.ads.googleads.v12.enums.types.access_reason", + "AccessRoleEnum": "google.ads.googleads.v12.enums.types.access_role", + "AccountBudgetProposalStatusEnum": "google.ads.googleads.v12.enums.types.account_budget_proposal_status", + "AccountBudgetProposalTypeEnum": "google.ads.googleads.v12.enums.types.account_budget_proposal_type", + "AccountBudgetStatusEnum": "google.ads.googleads.v12.enums.types.account_budget_status", + "AccountLinkStatusEnum": "google.ads.googleads.v12.enums.types.account_link_status", + "AdCustomizerPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.ad_customizer_placeholder_field", + "AdDestinationTypeEnum": "google.ads.googleads.v12.enums.types.ad_destination_type", + "AdGroupAdRotationModeEnum": "google.ads.googleads.v12.enums.types.ad_group_ad_rotation_mode", + "AdGroupAdStatusEnum": "google.ads.googleads.v12.enums.types.ad_group_ad_status", + "AdGroupCriterionApprovalStatusEnum": "google.ads.googleads.v12.enums.types.ad_group_criterion_approval_status", + "AdGroupCriterionStatusEnum": "google.ads.googleads.v12.enums.types.ad_group_criterion_status", + "AdGroupStatusEnum": "google.ads.googleads.v12.enums.types.ad_group_status", + "AdGroupTypeEnum": "google.ads.googleads.v12.enums.types.ad_group_type", + "AdNetworkTypeEnum": "google.ads.googleads.v12.enums.types.ad_network_type", + "AdServingOptimizationStatusEnum": "google.ads.googleads.v12.enums.types.ad_serving_optimization_status", + "AdStrengthEnum": "google.ads.googleads.v12.enums.types.ad_strength", + "AdTypeEnum": "google.ads.googleads.v12.enums.types.ad_type", + "AdvertisingChannelSubTypeEnum": "google.ads.googleads.v12.enums.types.advertising_channel_sub_type", + "AdvertisingChannelTypeEnum": "google.ads.googleads.v12.enums.types.advertising_channel_type", + "AffiliateLocationFeedRelationshipTypeEnum": "google.ads.googleads.v12.enums.types.affiliate_location_feed_relationship_type", + "AffiliateLocationPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.affiliate_location_placeholder_field", + "AgeRangeTypeEnum": "google.ads.googleads.v12.enums.types.age_range_type", + "AppCampaignAppStoreEnum": "google.ads.googleads.v12.enums.types.app_campaign_app_store", + "AppCampaignBiddingStrategyGoalTypeEnum": "google.ads.googleads.v12.enums.types.app_campaign_bidding_strategy_goal_type", + "AppPaymentModelTypeEnum": "google.ads.googleads.v12.enums.types.app_payment_model_type", + "AppPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.app_placeholder_field", + "AppStoreEnum": "google.ads.googleads.v12.enums.types.app_store", + "AppUrlOperatingSystemTypeEnum": "google.ads.googleads.v12.enums.types.app_url_operating_system_type", + "AssetFieldTypeEnum": "google.ads.googleads.v12.enums.types.asset_field_type", + "AssetGroupStatusEnum": "google.ads.googleads.v12.enums.types.asset_group_status", + "AssetLinkStatusEnum": "google.ads.googleads.v12.enums.types.asset_link_status", + "AssetPerformanceLabelEnum": "google.ads.googleads.v12.enums.types.asset_performance_label", + "AssetSetAssetStatusEnum": "google.ads.googleads.v12.enums.types.asset_set_asset_status", + "AssetSetLinkStatusEnum": "google.ads.googleads.v12.enums.types.asset_set_link_status", + "AssetSetStatusEnum": "google.ads.googleads.v12.enums.types.asset_set_status", + "AssetSetTypeEnum": "google.ads.googleads.v12.enums.types.asset_set_type", + "AssetSourceEnum": "google.ads.googleads.v12.enums.types.asset_source", + "AssetTypeEnum": "google.ads.googleads.v12.enums.types.asset_type", + "AsyncActionStatusEnum": "google.ads.googleads.v12.enums.types.async_action_status", + "AttributionModelEnum": "google.ads.googleads.v12.enums.types.attribution_model", + "AudienceInsightsDimensionEnum": "google.ads.googleads.v12.enums.types.audience_insights_dimension", + "AudienceStatusEnum": "google.ads.googleads.v12.enums.types.audience_status", + "BatchJobStatusEnum": "google.ads.googleads.v12.enums.types.batch_job_status", + "BiddingSourceEnum": "google.ads.googleads.v12.enums.types.bidding_source", + "BiddingStrategyStatusEnum": "google.ads.googleads.v12.enums.types.bidding_strategy_status", + "BiddingStrategySystemStatusEnum": "google.ads.googleads.v12.enums.types.bidding_strategy_system_status", + "BiddingStrategyTypeEnum": "google.ads.googleads.v12.enums.types.bidding_strategy_type", + "BidModifierSourceEnum": "google.ads.googleads.v12.enums.types.bid_modifier_source", + "BillingSetupStatusEnum": "google.ads.googleads.v12.enums.types.billing_setup_status", + "BrandSafetySuitabilityEnum": "google.ads.googleads.v12.enums.types.brand_safety_suitability", + "BudgetCampaignAssociationStatusEnum": "google.ads.googleads.v12.enums.types.budget_campaign_association_status", + "BudgetDeliveryMethodEnum": "google.ads.googleads.v12.enums.types.budget_delivery_method", + "BudgetPeriodEnum": "google.ads.googleads.v12.enums.types.budget_period", + "BudgetStatusEnum": "google.ads.googleads.v12.enums.types.budget_status", + "BudgetTypeEnum": "google.ads.googleads.v12.enums.types.budget_type", + "CallConversionReportingStateEnum": "google.ads.googleads.v12.enums.types.call_conversion_reporting_state", + "CalloutPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.callout_placeholder_field", + "CallPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.call_placeholder_field", + "CallToActionTypeEnum": "google.ads.googleads.v12.enums.types.call_to_action_type", + "CallTrackingDisplayLocationEnum": "google.ads.googleads.v12.enums.types.call_tracking_display_location", + "CallTypeEnum": "google.ads.googleads.v12.enums.types.call_type", + "CampaignCriterionStatusEnum": "google.ads.googleads.v12.enums.types.campaign_criterion_status", + "CampaignDraftStatusEnum": "google.ads.googleads.v12.enums.types.campaign_draft_status", + "CampaignExperimentTypeEnum": "google.ads.googleads.v12.enums.types.campaign_experiment_type", + "CampaignGroupStatusEnum": "google.ads.googleads.v12.enums.types.campaign_group_status", + "CampaignPrimaryStatusEnum": "google.ads.googleads.v12.enums.types.campaign_primary_status", + "CampaignPrimaryStatusReasonEnum": "google.ads.googleads.v12.enums.types.campaign_primary_status_reason", + "CampaignServingStatusEnum": "google.ads.googleads.v12.enums.types.campaign_serving_status", + "CampaignSharedSetStatusEnum": "google.ads.googleads.v12.enums.types.campaign_shared_set_status", + "CampaignStatusEnum": "google.ads.googleads.v12.enums.types.campaign_status", + "ChainRelationshipTypeEnum": "google.ads.googleads.v12.enums.types.chain_relationship_type", + "ChangeClientTypeEnum": "google.ads.googleads.v12.enums.types.change_client_type", + "ChangeEventResourceTypeEnum": "google.ads.googleads.v12.enums.types.change_event_resource_type", + "ChangeStatusOperationEnum": "google.ads.googleads.v12.enums.types.change_status_operation", + "ChangeStatusResourceTypeEnum": "google.ads.googleads.v12.enums.types.change_status_resource_type", + "ClickTypeEnum": "google.ads.googleads.v12.enums.types.click_type", + "CombinedAudienceStatusEnum": "google.ads.googleads.v12.enums.types.combined_audience_status", + "ContentLabelTypeEnum": "google.ads.googleads.v12.enums.types.content_label_type", + "ConversionActionCategoryEnum": "google.ads.googleads.v12.enums.types.conversion_action_category", + "ConversionActionCountingTypeEnum": "google.ads.googleads.v12.enums.types.conversion_action_counting_type", + "ConversionActionStatusEnum": "google.ads.googleads.v12.enums.types.conversion_action_status", + "ConversionActionTypeEnum": "google.ads.googleads.v12.enums.types.conversion_action_type", + "ConversionAdjustmentTypeEnum": "google.ads.googleads.v12.enums.types.conversion_adjustment_type", + "ConversionAttributionEventTypeEnum": "google.ads.googleads.v12.enums.types.conversion_attribution_event_type", + "ConversionCustomVariableStatusEnum": "google.ads.googleads.v12.enums.types.conversion_custom_variable_status", + "ConversionEnvironmentEnum": "google.ads.googleads.v12.enums.types.conversion_environment_enum", + "ConversionLagBucketEnum": "google.ads.googleads.v12.enums.types.conversion_lag_bucket", + "ConversionOrAdjustmentLagBucketEnum": "google.ads.googleads.v12.enums.types.conversion_or_adjustment_lag_bucket", + "ConversionOriginEnum": "google.ads.googleads.v12.enums.types.conversion_origin", + "ConversionTrackingStatusEnum": "google.ads.googleads.v12.enums.types.conversion_tracking_status_enum", + "ConversionValueRulePrimaryDimensionEnum": "google.ads.googleads.v12.enums.types.conversion_value_rule_primary_dimension", + "ConversionValueRuleSetStatusEnum": "google.ads.googleads.v12.enums.types.conversion_value_rule_set_status", + "ConversionValueRuleStatusEnum": "google.ads.googleads.v12.enums.types.conversion_value_rule_status", + "CriterionCategoryChannelAvailabilityModeEnum": "google.ads.googleads.v12.enums.types.criterion_category_channel_availability_mode", + "CriterionCategoryLocaleAvailabilityModeEnum": "google.ads.googleads.v12.enums.types.criterion_category_locale_availability_mode", + "CriterionSystemServingStatusEnum": "google.ads.googleads.v12.enums.types.criterion_system_serving_status", + "CriterionTypeEnum": "google.ads.googleads.v12.enums.types.criterion_type", + "CustomAudienceMemberTypeEnum": "google.ads.googleads.v12.enums.types.custom_audience_member_type", + "CustomAudienceStatusEnum": "google.ads.googleads.v12.enums.types.custom_audience_status", + "CustomAudienceTypeEnum": "google.ads.googleads.v12.enums.types.custom_audience_type", + "CustomConversionGoalStatusEnum": "google.ads.googleads.v12.enums.types.custom_conversion_goal_status", + "CustomerMatchUploadKeyTypeEnum": "google.ads.googleads.v12.enums.types.customer_match_upload_key_type", + "CustomerPayPerConversionEligibilityFailureReasonEnum": "google.ads.googleads.v12.enums.types.customer_pay_per_conversion_eligibility_failure_reason", + "CustomerStatusEnum": "google.ads.googleads.v12.enums.types.customer_status", + "CustomInterestMemberTypeEnum": "google.ads.googleads.v12.enums.types.custom_interest_member_type", + "CustomInterestStatusEnum": "google.ads.googleads.v12.enums.types.custom_interest_status", + "CustomInterestTypeEnum": "google.ads.googleads.v12.enums.types.custom_interest_type", + "CustomizerAttributeStatusEnum": "google.ads.googleads.v12.enums.types.customizer_attribute_status", + "CustomizerAttributeTypeEnum": "google.ads.googleads.v12.enums.types.customizer_attribute_type", + "CustomizerValueStatusEnum": "google.ads.googleads.v12.enums.types.customizer_value_status", + "CustomPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.custom_placeholder_field", + "DataDrivenModelStatusEnum": "google.ads.googleads.v12.enums.types.data_driven_model_status", + "DayOfWeekEnum": "google.ads.googleads.v12.enums.types.day_of_week", + "DeviceEnum": "google.ads.googleads.v12.enums.types.device", + "DisplayAdFormatSettingEnum": "google.ads.googleads.v12.enums.types.display_ad_format_setting", + "DisplayUploadProductTypeEnum": "google.ads.googleads.v12.enums.types.display_upload_product_type", + "DistanceBucketEnum": "google.ads.googleads.v12.enums.types.distance_bucket", + "DsaPageFeedCriterionFieldEnum": "google.ads.googleads.v12.enums.types.dsa_page_feed_criterion_field", + "EducationPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.education_placeholder_field", + "ExperimentMetricDirectionEnum": "google.ads.googleads.v12.enums.types.experiment_metric_direction", + "ExperimentMetricEnum": "google.ads.googleads.v12.enums.types.experiment_metric", + "ExperimentStatusEnum": "google.ads.googleads.v12.enums.types.experiment_status", + "ExperimentTypeEnum": "google.ads.googleads.v12.enums.types.experiment_type", + "ExtensionSettingDeviceEnum": "google.ads.googleads.v12.enums.types.extension_setting_device", + "ExtensionTypeEnum": "google.ads.googleads.v12.enums.types.extension_type", + "ExternalConversionSourceEnum": "google.ads.googleads.v12.enums.types.external_conversion_source", + "FeedAttributeTypeEnum": "google.ads.googleads.v12.enums.types.feed_attribute_type", + "FeedItemQualityApprovalStatusEnum": "google.ads.googleads.v12.enums.types.feed_item_quality_approval_status", + "FeedItemQualityDisapprovalReasonEnum": "google.ads.googleads.v12.enums.types.feed_item_quality_disapproval_reason", + "FeedItemSetStatusEnum": "google.ads.googleads.v12.enums.types.feed_item_set_status", + "FeedItemSetStringFilterTypeEnum": "google.ads.googleads.v12.enums.types.feed_item_set_string_filter_type", + "FeedItemStatusEnum": "google.ads.googleads.v12.enums.types.feed_item_status", + "FeedItemTargetDeviceEnum": "google.ads.googleads.v12.enums.types.feed_item_target_device", + "FeedItemTargetStatusEnum": "google.ads.googleads.v12.enums.types.feed_item_target_status", + "FeedItemTargetTypeEnum": "google.ads.googleads.v12.enums.types.feed_item_target_type", + "FeedItemValidationStatusEnum": "google.ads.googleads.v12.enums.types.feed_item_validation_status", + "FeedLinkStatusEnum": "google.ads.googleads.v12.enums.types.feed_link_status", + "FeedMappingCriterionTypeEnum": "google.ads.googleads.v12.enums.types.feed_mapping_criterion_type", + "FeedMappingStatusEnum": "google.ads.googleads.v12.enums.types.feed_mapping_status", + "FeedOriginEnum": "google.ads.googleads.v12.enums.types.feed_origin", + "FeedStatusEnum": "google.ads.googleads.v12.enums.types.feed_status", + "FlightPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.flight_placeholder_field", + "FrequencyCapEventTypeEnum": "google.ads.googleads.v12.enums.types.frequency_cap_event_type", + "FrequencyCapLevelEnum": "google.ads.googleads.v12.enums.types.frequency_cap_level", + "FrequencyCapTimeUnitEnum": "google.ads.googleads.v12.enums.types.frequency_cap_time_unit", + "GenderTypeEnum": "google.ads.googleads.v12.enums.types.gender_type", + "GeoTargetConstantStatusEnum": "google.ads.googleads.v12.enums.types.geo_target_constant_status", + "GeoTargetingRestrictionEnum": "google.ads.googleads.v12.enums.types.geo_targeting_restriction", + "GeoTargetingTypeEnum": "google.ads.googleads.v12.enums.types.geo_targeting_type", + "GoalConfigLevelEnum": "google.ads.googleads.v12.enums.types.goal_config_level", + "GoogleAdsFieldCategoryEnum": "google.ads.googleads.v12.enums.types.google_ads_field_category", + "GoogleAdsFieldDataTypeEnum": "google.ads.googleads.v12.enums.types.google_ads_field_data_type", + "GoogleVoiceCallStatusEnum": "google.ads.googleads.v12.enums.types.google_voice_call_status", + "HotelDateSelectionTypeEnum": "google.ads.googleads.v12.enums.types.hotel_date_selection_type", + "HotelPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.hotel_placeholder_field", + "HotelPriceBucketEnum": "google.ads.googleads.v12.enums.types.hotel_price_bucket", + "HotelRateTypeEnum": "google.ads.googleads.v12.enums.types.hotel_rate_type", + "HotelReconciliationStatusEnum": "google.ads.googleads.v12.enums.types.hotel_reconciliation_status", + "ImagePlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.image_placeholder_field", + "IncomeRangeTypeEnum": "google.ads.googleads.v12.enums.types.income_range_type", + "InteractionEventTypeEnum": "google.ads.googleads.v12.enums.types.interaction_event_type", + "InteractionTypeEnum": "google.ads.googleads.v12.enums.types.interaction_type", + "InvoiceTypeEnum": "google.ads.googleads.v12.enums.types.invoice_type", + "JobPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.job_placeholder_field", + "KeywordMatchTypeEnum": "google.ads.googleads.v12.enums.types.keyword_match_type", + "KeywordPlanAggregateMetricTypeEnum": "google.ads.googleads.v12.enums.types.keyword_plan_aggregate_metric_type", + "KeywordPlanCompetitionLevelEnum": "google.ads.googleads.v12.enums.types.keyword_plan_competition_level", + "KeywordPlanConceptGroupTypeEnum": "google.ads.googleads.v12.enums.types.keyword_plan_concept_group_type", + "KeywordPlanForecastIntervalEnum": "google.ads.googleads.v12.enums.types.keyword_plan_forecast_interval", + "KeywordPlanKeywordAnnotationEnum": "google.ads.googleads.v12.enums.types.keyword_plan_keyword_annotation", + "KeywordPlanNetworkEnum": "google.ads.googleads.v12.enums.types.keyword_plan_network", + "LabelStatusEnum": "google.ads.googleads.v12.enums.types.label_status", + "LeadFormCallToActionTypeEnum": "google.ads.googleads.v12.enums.types.lead_form_call_to_action_type", + "LeadFormDesiredIntentEnum": "google.ads.googleads.v12.enums.types.lead_form_desired_intent", + "LeadFormFieldUserInputTypeEnum": "google.ads.googleads.v12.enums.types.lead_form_field_user_input_type", + "LeadFormPostSubmitCallToActionTypeEnum": "google.ads.googleads.v12.enums.types.lead_form_post_submit_call_to_action_type", + "LegacyAppInstallAdAppStoreEnum": "google.ads.googleads.v12.enums.types.legacy_app_install_ad_app_store", + "LinkedAccountTypeEnum": "google.ads.googleads.v12.enums.types.linked_account_type", + "ListingGroupFilterBiddingCategoryLevelEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_bidding_category_level", + "ListingGroupFilterCustomAttributeIndexEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_custom_attribute_index", + "ListingGroupFilterProductChannelEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_product_channel", + "ListingGroupFilterProductConditionEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_product_condition", + "ListingGroupFilterProductTypeLevelEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_product_type_level", + "ListingGroupFilterTypeEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_type_enum", + "ListingGroupFilterVerticalEnum": "google.ads.googleads.v12.enums.types.listing_group_filter_vertical", + "ListingGroupTypeEnum": "google.ads.googleads.v12.enums.types.listing_group_type", + "LocalPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.local_placeholder_field", + "LocationExtensionTargetingCriterionFieldEnum": "google.ads.googleads.v12.enums.types.location_extension_targeting_criterion_field", + "LocationGroupRadiusUnitsEnum": "google.ads.googleads.v12.enums.types.location_group_radius_units", + "LocationOwnershipTypeEnum": "google.ads.googleads.v12.enums.types.location_ownership_type", + "LocationPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.location_placeholder_field", + "LocationSourceTypeEnum": "google.ads.googleads.v12.enums.types.location_source_type", + "LocationStringFilterTypeEnum": "google.ads.googleads.v12.enums.types.location_string_filter_type", + "ManagerLinkStatusEnum": "google.ads.googleads.v12.enums.types.manager_link_status", + "MatchingFunctionContextTypeEnum": "google.ads.googleads.v12.enums.types.matching_function_context_type", + "MatchingFunctionOperatorEnum": "google.ads.googleads.v12.enums.types.matching_function_operator", + "MediaTypeEnum": "google.ads.googleads.v12.enums.types.media_type", + "MerchantCenterLinkStatusEnum": "google.ads.googleads.v12.enums.types.merchant_center_link_status", + "MessagePlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.message_placeholder_field", + "MimeTypeEnum": "google.ads.googleads.v12.enums.types.mime_type", + "MinuteOfHourEnum": "google.ads.googleads.v12.enums.types.minute_of_hour", + "MobileAppVendorEnum": "google.ads.googleads.v12.enums.types.mobile_app_vendor", + "MobileDeviceTypeEnum": "google.ads.googleads.v12.enums.types.mobile_device_type", + "MonthOfYearEnum": "google.ads.googleads.v12.enums.types.month_of_year", + "NegativeGeoTargetTypeEnum": "google.ads.googleads.v12.enums.types.negative_geo_target_type", + "OfflineUserDataJobFailureReasonEnum": "google.ads.googleads.v12.enums.types.offline_user_data_job_failure_reason", + "OfflineUserDataJobMatchRateRangeEnum": "google.ads.googleads.v12.enums.types.offline_user_data_job_match_rate_range", + "OfflineUserDataJobStatusEnum": "google.ads.googleads.v12.enums.types.offline_user_data_job_status", + "OfflineUserDataJobTypeEnum": "google.ads.googleads.v12.enums.types.offline_user_data_job_type", + "OperatingSystemVersionOperatorTypeEnum": "google.ads.googleads.v12.enums.types.operating_system_version_operator_type", + "OptimizationGoalTypeEnum": "google.ads.googleads.v12.enums.types.optimization_goal_type", + "ParentalStatusTypeEnum": "google.ads.googleads.v12.enums.types.parental_status_type", + "PaymentModeEnum": "google.ads.googleads.v12.enums.types.payment_mode", + "PerformanceMaxUpgradeStatusEnum": "google.ads.googleads.v12.enums.types.performance_max_upgrade_status", + "PlaceholderTypeEnum": "google.ads.googleads.v12.enums.types.placeholder_type", + "PlacementTypeEnum": "google.ads.googleads.v12.enums.types.placement_type", + "PolicyApprovalStatusEnum": "google.ads.googleads.v12.enums.types.policy_approval_status", + "PolicyReviewStatusEnum": "google.ads.googleads.v12.enums.types.policy_review_status", + "PolicyTopicEntryTypeEnum": "google.ads.googleads.v12.enums.types.policy_topic_entry_type", + "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum": "google.ads.googleads.v12.enums.types.policy_topic_evidence_destination_mismatch_url_type", + "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum": "google.ads.googleads.v12.enums.types.policy_topic_evidence_destination_not_working_device", + "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum": "google.ads.googleads.v12.enums.types.policy_topic_evidence_destination_not_working_dns_error_type", + "PositiveGeoTargetTypeEnum": "google.ads.googleads.v12.enums.types.positive_geo_target_type", + "PreferredContentTypeEnum": "google.ads.googleads.v12.enums.types.preferred_content_type", + "PriceExtensionPriceQualifierEnum": "google.ads.googleads.v12.enums.types.price_extension_price_qualifier", + "PriceExtensionPriceUnitEnum": "google.ads.googleads.v12.enums.types.price_extension_price_unit", + "PriceExtensionTypeEnum": "google.ads.googleads.v12.enums.types.price_extension_type", + "PricePlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.price_placeholder_field", + "ProductBiddingCategoryLevelEnum": "google.ads.googleads.v12.enums.types.product_bidding_category_level", + "ProductBiddingCategoryStatusEnum": "google.ads.googleads.v12.enums.types.product_bidding_category_status", + "ProductChannelEnum": "google.ads.googleads.v12.enums.types.product_channel", + "ProductChannelExclusivityEnum": "google.ads.googleads.v12.enums.types.product_channel_exclusivity", + "ProductConditionEnum": "google.ads.googleads.v12.enums.types.product_condition", + "ProductCustomAttributeIndexEnum": "google.ads.googleads.v12.enums.types.product_custom_attribute_index", + "ProductTypeLevelEnum": "google.ads.googleads.v12.enums.types.product_type_level", + "PromotionExtensionDiscountModifierEnum": "google.ads.googleads.v12.enums.types.promotion_extension_discount_modifier", + "PromotionExtensionOccasionEnum": "google.ads.googleads.v12.enums.types.promotion_extension_occasion", + "PromotionPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.promotion_placeholder_field", + "ProximityRadiusUnitsEnum": "google.ads.googleads.v12.enums.types.proximity_radius_units", + "QualityScoreBucketEnum": "google.ads.googleads.v12.enums.types.quality_score_bucket", + "ReachPlanAgeRangeEnum": "google.ads.googleads.v12.enums.types.reach_plan_age_range", + "ReachPlanNetworkEnum": "google.ads.googleads.v12.enums.types.reach_plan_network", + "RealEstatePlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.real_estate_placeholder_field", + "RecommendationTypeEnum": "google.ads.googleads.v12.enums.types.recommendation_type", + "ResourceChangeOperationEnum": "google.ads.googleads.v12.enums.types.resource_change_operation", + "ResourceLimitTypeEnum": "google.ads.googleads.v12.enums.types.resource_limit_type", + "ResponseContentTypeEnum": "google.ads.googleads.v12.enums.types.response_content_type", + "SearchEngineResultsPageTypeEnum": "google.ads.googleads.v12.enums.types.search_engine_results_page_type", + "SearchTermMatchTypeEnum": "google.ads.googleads.v12.enums.types.search_term_match_type", + "SearchTermTargetingStatusEnum": "google.ads.googleads.v12.enums.types.search_term_targeting_status", + "SeasonalityEventScopeEnum": "google.ads.googleads.v12.enums.types.seasonality_event_scope", + "SeasonalityEventStatusEnum": "google.ads.googleads.v12.enums.types.seasonality_event_status", + "ServedAssetFieldTypeEnum": "google.ads.googleads.v12.enums.types.served_asset_field_type", + "SharedSetStatusEnum": "google.ads.googleads.v12.enums.types.shared_set_status", + "SharedSetTypeEnum": "google.ads.googleads.v12.enums.types.shared_set_type", + "SimulationModificationMethodEnum": "google.ads.googleads.v12.enums.types.simulation_modification_method", + "SimulationTypeEnum": "google.ads.googleads.v12.enums.types.simulation_type", + "SitelinkPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.sitelink_placeholder_field", + "SkAdNetworkAdEventTypeEnum": "google.ads.googleads.v12.enums.types.sk_ad_network_ad_event_type", + "SkAdNetworkAttributionCreditEnum": "google.ads.googleads.v12.enums.types.sk_ad_network_attribution_credit", + "SkAdNetworkUserTypeEnum": "google.ads.googleads.v12.enums.types.sk_ad_network_user_type", + "SlotEnum": "google.ads.googleads.v12.enums.types.slot", + "SpendingLimitTypeEnum": "google.ads.googleads.v12.enums.types.spending_limit_type", + "StructuredSnippetPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.structured_snippet_placeholder_field", + "SummaryRowSettingEnum": "google.ads.googleads.v12.enums.types.summary_row_setting", + "SystemManagedResourceSourceEnum": "google.ads.googleads.v12.enums.types.system_managed_entity_source", + "TargetCpaOptInRecommendationGoalEnum": "google.ads.googleads.v12.enums.types.target_cpa_opt_in_recommendation_goal", + "TargetImpressionShareLocationEnum": "google.ads.googleads.v12.enums.types.target_impression_share_location", + "TargetingDimensionEnum": "google.ads.googleads.v12.enums.types.targeting_dimension", + "TimeTypeEnum": "google.ads.googleads.v12.enums.types.time_type", + "TrackingCodePageFormatEnum": "google.ads.googleads.v12.enums.types.tracking_code_page_format", + "TrackingCodeTypeEnum": "google.ads.googleads.v12.enums.types.tracking_code_type", + "TravelPlaceholderFieldEnum": "google.ads.googleads.v12.enums.types.travel_placeholder_field", + "UserIdentifierSourceEnum": "google.ads.googleads.v12.enums.types.user_identifier_source", + "UserInterestTaxonomyTypeEnum": "google.ads.googleads.v12.enums.types.user_interest_taxonomy_type", + "UserListAccessStatusEnum": "google.ads.googleads.v12.enums.types.user_list_access_status", + "UserListClosingReasonEnum": "google.ads.googleads.v12.enums.types.user_list_closing_reason", + "UserListCombinedRuleOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_combined_rule_operator", + "UserListCrmDataSourceTypeEnum": "google.ads.googleads.v12.enums.types.user_list_crm_data_source_type", + "UserListDateRuleItemOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_date_rule_item_operator", + "UserListFlexibleRuleOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_flexible_rule_operator", + "UserListLogicalRuleOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_logical_rule_operator", + "UserListMembershipStatusEnum": "google.ads.googleads.v12.enums.types.user_list_membership_status", + "UserListNumberRuleItemOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_number_rule_item_operator", + "UserListPrepopulationStatusEnum": "google.ads.googleads.v12.enums.types.user_list_prepopulation_status", + "UserListRuleTypeEnum": "google.ads.googleads.v12.enums.types.user_list_rule_type", + "UserListSizeRangeEnum": "google.ads.googleads.v12.enums.types.user_list_size_range", + "UserListStringRuleItemOperatorEnum": "google.ads.googleads.v12.enums.types.user_list_string_rule_item_operator", + "UserListTypeEnum": "google.ads.googleads.v12.enums.types.user_list_type", + "ValueRuleDeviceTypeEnum": "google.ads.googleads.v12.enums.types.value_rule_device_type", + "ValueRuleGeoLocationMatchTypeEnum": "google.ads.googleads.v12.enums.types.value_rule_geo_location_match_type", + "ValueRuleOperationEnum": "google.ads.googleads.v12.enums.types.value_rule_operation", + "ValueRuleSetAttachmentTypeEnum": "google.ads.googleads.v12.enums.types.value_rule_set_attachment_type", + "ValueRuleSetDimensionEnum": "google.ads.googleads.v12.enums.types.value_rule_set_dimension", + "VanityPharmaDisplayUrlModeEnum": "google.ads.googleads.v12.enums.types.vanity_pharma_display_url_mode", + "VanityPharmaTextEnum": "google.ads.googleads.v12.enums.types.vanity_pharma_text", + "VideoThumbnailEnum": "google.ads.googleads.v12.enums.types.video_thumbnail", + "WebpageConditionOperandEnum": "google.ads.googleads.v12.enums.types.webpage_condition_operand", + "WebpageConditionOperatorEnum": "google.ads.googleads.v12.enums.types.webpage_condition_operator", + "AccessInvitationErrorEnum": "google.ads.googleads.v12.errors.types.access_invitation_error", + "AccountBudgetProposalErrorEnum": "google.ads.googleads.v12.errors.types.account_budget_proposal_error", + "AccountLinkErrorEnum": "google.ads.googleads.v12.errors.types.account_link_error", + "AdCustomizerErrorEnum": "google.ads.googleads.v12.errors.types.ad_customizer_error", + "AdErrorEnum": "google.ads.googleads.v12.errors.types.ad_error", + "AdGroupAdErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_ad_error", + "AdGroupBidModifierErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_bid_modifier_error", + "AdGroupCriterionCustomizerErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_criterion_customizer_error", + "AdGroupCriterionErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_criterion_error", + "AdGroupCustomizerErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_customizer_error", + "AdGroupErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_error", + "AdGroupFeedErrorEnum": "google.ads.googleads.v12.errors.types.ad_group_feed_error", + "AdParameterErrorEnum": "google.ads.googleads.v12.errors.types.ad_parameter_error", + "AdSharingErrorEnum": "google.ads.googleads.v12.errors.types.ad_sharing_error", + "AdxErrorEnum": "google.ads.googleads.v12.errors.types.adx_error", + "AssetErrorEnum": "google.ads.googleads.v12.errors.types.asset_error", + "AssetGroupAssetErrorEnum": "google.ads.googleads.v12.errors.types.asset_group_asset_error", + "AssetGroupErrorEnum": "google.ads.googleads.v12.errors.types.asset_group_error", + "AssetGroupListingGroupFilterErrorEnum": "google.ads.googleads.v12.errors.types.asset_group_listing_group_filter_error", + "AssetLinkErrorEnum": "google.ads.googleads.v12.errors.types.asset_link_error", + "AssetSetAssetErrorEnum": "google.ads.googleads.v12.errors.types.asset_set_asset_error", + "AssetSetErrorEnum": "google.ads.googleads.v12.errors.types.asset_set_error", + "AssetSetLinkErrorEnum": "google.ads.googleads.v12.errors.types.asset_set_link_error", + "AudienceErrorEnum": "google.ads.googleads.v12.errors.types.audience_error", + "AudienceInsightsErrorEnum": "google.ads.googleads.v12.errors.types.audience_insights_error", + "AuthenticationErrorEnum": "google.ads.googleads.v12.errors.types.authentication_error", + "AuthorizationErrorEnum": "google.ads.googleads.v12.errors.types.authorization_error", + "BatchJobErrorEnum": "google.ads.googleads.v12.errors.types.batch_job_error", + "BiddingErrorEnum": "google.ads.googleads.v12.errors.types.bidding_error", + "BiddingStrategyErrorEnum": "google.ads.googleads.v12.errors.types.bidding_strategy_error", + "BillingSetupErrorEnum": "google.ads.googleads.v12.errors.types.billing_setup_error", + "CampaignBudgetErrorEnum": "google.ads.googleads.v12.errors.types.campaign_budget_error", + "CampaignConversionGoalErrorEnum": "google.ads.googleads.v12.errors.types.campaign_conversion_goal_error", + "CampaignCriterionErrorEnum": "google.ads.googleads.v12.errors.types.campaign_criterion_error", + "CampaignCustomizerErrorEnum": "google.ads.googleads.v12.errors.types.campaign_customizer_error", + "CampaignDraftErrorEnum": "google.ads.googleads.v12.errors.types.campaign_draft_error", + "CampaignErrorEnum": "google.ads.googleads.v12.errors.types.campaign_error", + "CampaignExperimentErrorEnum": "google.ads.googleads.v12.errors.types.campaign_experiment_error", + "CampaignFeedErrorEnum": "google.ads.googleads.v12.errors.types.campaign_feed_error", + "CampaignSharedSetErrorEnum": "google.ads.googleads.v12.errors.types.campaign_shared_set_error", + "ChangeEventErrorEnum": "google.ads.googleads.v12.errors.types.change_event_error", + "ChangeStatusErrorEnum": "google.ads.googleads.v12.errors.types.change_status_error", + "CollectionSizeErrorEnum": "google.ads.googleads.v12.errors.types.collection_size_error", + "ContextErrorEnum": "google.ads.googleads.v12.errors.types.context_error", + "ConversionActionErrorEnum": "google.ads.googleads.v12.errors.types.conversion_action_error", + "ConversionAdjustmentUploadErrorEnum": "google.ads.googleads.v12.errors.types.conversion_adjustment_upload_error", + "ConversionCustomVariableErrorEnum": "google.ads.googleads.v12.errors.types.conversion_custom_variable_error", + "ConversionGoalCampaignConfigErrorEnum": "google.ads.googleads.v12.errors.types.conversion_goal_campaign_config_error", + "ConversionUploadErrorEnum": "google.ads.googleads.v12.errors.types.conversion_upload_error", + "ConversionValueRuleErrorEnum": "google.ads.googleads.v12.errors.types.conversion_value_rule_error", + "ConversionValueRuleSetErrorEnum": "google.ads.googleads.v12.errors.types.conversion_value_rule_set_error", + "CountryCodeErrorEnum": "google.ads.googleads.v12.errors.types.country_code_error", + "CriterionErrorEnum": "google.ads.googleads.v12.errors.types.criterion_error", + "CurrencyCodeErrorEnum": "google.ads.googleads.v12.errors.types.currency_code_error", + "CustomAudienceErrorEnum": "google.ads.googleads.v12.errors.types.custom_audience_error", + "CustomConversionGoalErrorEnum": "google.ads.googleads.v12.errors.types.custom_conversion_goal_error", + "CustomerClientLinkErrorEnum": "google.ads.googleads.v12.errors.types.customer_client_link_error", + "CustomerCustomizerErrorEnum": "google.ads.googleads.v12.errors.types.customer_customizer_error", + "CustomerErrorEnum": "google.ads.googleads.v12.errors.types.customer_error", + "CustomerFeedErrorEnum": "google.ads.googleads.v12.errors.types.customer_feed_error", + "CustomerManagerLinkErrorEnum": "google.ads.googleads.v12.errors.types.customer_manager_link_error", + "CustomerUserAccessErrorEnum": "google.ads.googleads.v12.errors.types.customer_user_access_error", + "CustomInterestErrorEnum": "google.ads.googleads.v12.errors.types.custom_interest_error", + "CustomizerAttributeErrorEnum": "google.ads.googleads.v12.errors.types.customizer_attribute_error", + "DatabaseErrorEnum": "google.ads.googleads.v12.errors.types.database_error", + "DateErrorEnum": "google.ads.googleads.v12.errors.types.date_error", + "DateRangeErrorEnum": "google.ads.googleads.v12.errors.types.date_range_error", + "DistinctErrorEnum": "google.ads.googleads.v12.errors.types.distinct_error", + "EnumErrorEnum": "google.ads.googleads.v12.errors.types.enum_error", + "ErrorCode": "google.ads.googleads.v12.errors.types.errors", + "ErrorDetails": "google.ads.googleads.v12.errors.types.errors", + "ErrorLocation": "google.ads.googleads.v12.errors.types.errors", + "ExperimentArmErrorEnum": "google.ads.googleads.v12.errors.types.experiment_arm_error", + "ExperimentErrorEnum": "google.ads.googleads.v12.errors.types.experiment_error", + "ExtensionFeedItemErrorEnum": "google.ads.googleads.v12.errors.types.extension_feed_item_error", + "ExtensionSettingErrorEnum": "google.ads.googleads.v12.errors.types.extension_setting_error", + "FeedAttributeReferenceErrorEnum": "google.ads.googleads.v12.errors.types.feed_attribute_reference_error", + "FeedErrorEnum": "google.ads.googleads.v12.errors.types.feed_error", + "FeedItemErrorEnum": "google.ads.googleads.v12.errors.types.feed_item_error", + "FeedItemSetErrorEnum": "google.ads.googleads.v12.errors.types.feed_item_set_error", + "FeedItemSetLinkErrorEnum": "google.ads.googleads.v12.errors.types.feed_item_set_link_error", + "FeedItemTargetErrorEnum": "google.ads.googleads.v12.errors.types.feed_item_target_error", + "FeedItemValidationErrorEnum": "google.ads.googleads.v12.errors.types.feed_item_validation_error", + "FeedMappingErrorEnum": "google.ads.googleads.v12.errors.types.feed_mapping_error", + "FieldErrorEnum": "google.ads.googleads.v12.errors.types.field_error", + "FieldMaskErrorEnum": "google.ads.googleads.v12.errors.types.field_mask_error", + "FunctionErrorEnum": "google.ads.googleads.v12.errors.types.function_error", + "FunctionParsingErrorEnum": "google.ads.googleads.v12.errors.types.function_parsing_error", + "GeoTargetConstantSuggestionErrorEnum": "google.ads.googleads.v12.errors.types.geo_target_constant_suggestion_error", + "GoogleAdsError": "google.ads.googleads.v12.errors.types.errors", + "GoogleAdsFailure": "google.ads.googleads.v12.errors.types.errors", + "HeaderErrorEnum": "google.ads.googleads.v12.errors.types.header_error", + "IdErrorEnum": "google.ads.googleads.v12.errors.types.id_error", + "ImageErrorEnum": "google.ads.googleads.v12.errors.types.image_error", + "InternalErrorEnum": "google.ads.googleads.v12.errors.types.internal_error", + "InvoiceErrorEnum": "google.ads.googleads.v12.errors.types.invoice_error", + "KeywordPlanAdGroupErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_ad_group_error", + "KeywordPlanAdGroupKeywordErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_ad_group_keyword_error", + "KeywordPlanCampaignErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_campaign_error", + "KeywordPlanCampaignKeywordErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_campaign_keyword_error", + "KeywordPlanErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_error", + "KeywordPlanIdeaErrorEnum": "google.ads.googleads.v12.errors.types.keyword_plan_idea_error", + "LabelErrorEnum": "google.ads.googleads.v12.errors.types.label_error", + "LanguageCodeErrorEnum": "google.ads.googleads.v12.errors.types.language_code_error", + "ListOperationErrorEnum": "google.ads.googleads.v12.errors.types.list_operation_error", + "ManagerLinkErrorEnum": "google.ads.googleads.v12.errors.types.manager_link_error", + "MediaBundleErrorEnum": "google.ads.googleads.v12.errors.types.media_bundle_error", + "MediaFileErrorEnum": "google.ads.googleads.v12.errors.types.media_file_error", + "MediaUploadErrorEnum": "google.ads.googleads.v12.errors.types.media_upload_error", + "MerchantCenterErrorEnum": "google.ads.googleads.v12.errors.types.merchant_center_error", + "MultiplierErrorEnum": "google.ads.googleads.v12.errors.types.multiplier_error", + "MutateErrorEnum": "google.ads.googleads.v12.errors.types.mutate_error", + "NewResourceCreationErrorEnum": "google.ads.googleads.v12.errors.types.new_resource_creation_error", + "NotAllowlistedErrorEnum": "google.ads.googleads.v12.errors.types.not_allowlisted_error", + "NotEmptyErrorEnum": "google.ads.googleads.v12.errors.types.not_empty_error", + "NullErrorEnum": "google.ads.googleads.v12.errors.types.null_error", + "OfflineUserDataJobErrorEnum": "google.ads.googleads.v12.errors.types.offline_user_data_job_error", + "OperationAccessDeniedErrorEnum": "google.ads.googleads.v12.errors.types.operation_access_denied_error", + "OperatorErrorEnum": "google.ads.googleads.v12.errors.types.operator_error", + "PartialFailureErrorEnum": "google.ads.googleads.v12.errors.types.partial_failure_error", + "PaymentsAccountErrorEnum": "google.ads.googleads.v12.errors.types.payments_account_error", + "PolicyFindingDetails": "google.ads.googleads.v12.errors.types.errors", + "PolicyFindingErrorEnum": "google.ads.googleads.v12.errors.types.policy_finding_error", + "PolicyValidationParameterErrorEnum": "google.ads.googleads.v12.errors.types.policy_validation_parameter_error", + "PolicyViolationDetails": "google.ads.googleads.v12.errors.types.errors", + "PolicyViolationErrorEnum": "google.ads.googleads.v12.errors.types.policy_violation_error", + "QueryErrorEnum": "google.ads.googleads.v12.errors.types.query_error", + "QuotaErrorDetails": "google.ads.googleads.v12.errors.types.errors", + "QuotaErrorEnum": "google.ads.googleads.v12.errors.types.quota_error", + "RangeErrorEnum": "google.ads.googleads.v12.errors.types.range_error", + "ReachPlanErrorEnum": "google.ads.googleads.v12.errors.types.reach_plan_error", + "RecommendationErrorEnum": "google.ads.googleads.v12.errors.types.recommendation_error", + "RegionCodeErrorEnum": "google.ads.googleads.v12.errors.types.region_code_error", + "RequestErrorEnum": "google.ads.googleads.v12.errors.types.request_error", + "ResourceAccessDeniedErrorEnum": "google.ads.googleads.v12.errors.types.resource_access_denied_error", + "ResourceCountDetails": "google.ads.googleads.v12.errors.types.errors", + "ResourceCountLimitExceededErrorEnum": "google.ads.googleads.v12.errors.types.resource_count_limit_exceeded_error", + "SettingErrorEnum": "google.ads.googleads.v12.errors.types.setting_error", + "SharedCriterionErrorEnum": "google.ads.googleads.v12.errors.types.shared_criterion_error", + "SharedSetErrorEnum": "google.ads.googleads.v12.errors.types.shared_set_error", + "SizeLimitErrorEnum": "google.ads.googleads.v12.errors.types.size_limit_error", + "SmartCampaignErrorEnum": "google.ads.googleads.v12.errors.types.smart_campaign_error", + "StringFormatErrorEnum": "google.ads.googleads.v12.errors.types.string_format_error", + "StringLengthErrorEnum": "google.ads.googleads.v12.errors.types.string_length_error", + "ThirdPartyAppAnalyticsLinkErrorEnum": "google.ads.googleads.v12.errors.types.third_party_app_analytics_link_error", + "TimeZoneErrorEnum": "google.ads.googleads.v12.errors.types.time_zone_error", + "UrlFieldErrorEnum": "google.ads.googleads.v12.errors.types.url_field_error", + "UserDataErrorEnum": "google.ads.googleads.v12.errors.types.user_data_error", + "UserListErrorEnum": "google.ads.googleads.v12.errors.types.user_list_error", + "YoutubeVideoRegistrationErrorEnum": "google.ads.googleads.v12.errors.types.youtube_video_registration_error", + "AccessibleBiddingStrategy": "google.ads.googleads.v12.resources.types.accessible_bidding_strategy", + "AccountBudget": "google.ads.googleads.v12.resources.types.account_budget", + "AccountBudgetProposal": "google.ads.googleads.v12.resources.types.account_budget_proposal", + "AccountLink": "google.ads.googleads.v12.resources.types.account_link", + "Ad": "google.ads.googleads.v12.resources.types.ad", + "AdGroup": "google.ads.googleads.v12.resources.types.ad_group", + "AdGroupAd": "google.ads.googleads.v12.resources.types.ad_group_ad", + "AdGroupAdAssetCombinationView": "google.ads.googleads.v12.resources.types.ad_group_ad_asset_combination_view", + "AdGroupAdAssetPolicySummary": "google.ads.googleads.v12.resources.types.ad_group_ad_asset_view", + "AdGroupAdAssetView": "google.ads.googleads.v12.resources.types.ad_group_ad_asset_view", + "AdGroupAdLabel": "google.ads.googleads.v12.resources.types.ad_group_ad_label", + "AdGroupAdPolicySummary": "google.ads.googleads.v12.resources.types.ad_group_ad", + "AdGroupAsset": "google.ads.googleads.v12.resources.types.ad_group_asset", + "AdGroupAssetSet": "google.ads.googleads.v12.resources.types.ad_group_asset_set", + "AdGroupAudienceView": "google.ads.googleads.v12.resources.types.ad_group_audience_view", + "AdGroupBidModifier": "google.ads.googleads.v12.resources.types.ad_group_bid_modifier", + "AdGroupCriterion": "google.ads.googleads.v12.resources.types.ad_group_criterion", + "AdGroupCriterionCustomizer": "google.ads.googleads.v12.resources.types.ad_group_criterion_customizer", + "AdGroupCriterionLabel": "google.ads.googleads.v12.resources.types.ad_group_criterion_label", + "AdGroupCriterionSimulation": "google.ads.googleads.v12.resources.types.ad_group_criterion_simulation", + "AdGroupCustomizer": "google.ads.googleads.v12.resources.types.ad_group_customizer", + "AdGroupExtensionSetting": "google.ads.googleads.v12.resources.types.ad_group_extension_setting", + "AdGroupFeed": "google.ads.googleads.v12.resources.types.ad_group_feed", + "AdGroupLabel": "google.ads.googleads.v12.resources.types.ad_group_label", + "AdGroupSimulation": "google.ads.googleads.v12.resources.types.ad_group_simulation", + "AdParameter": "google.ads.googleads.v12.resources.types.ad_parameter", + "AdScheduleView": "google.ads.googleads.v12.resources.types.ad_schedule_view", + "AdvertisingPartnerLinkIdentifier": "google.ads.googleads.v12.resources.types.account_link", + "AgeRangeView": "google.ads.googleads.v12.resources.types.age_range_view", + "Asset": "google.ads.googleads.v12.resources.types.asset", + "AssetFieldTypeView": "google.ads.googleads.v12.resources.types.asset_field_type_view", + "AssetGroup": "google.ads.googleads.v12.resources.types.asset_group", + "AssetGroupAsset": "google.ads.googleads.v12.resources.types.asset_group_asset", + "AssetGroupListingGroupFilter": "google.ads.googleads.v12.resources.types.asset_group_listing_group_filter", + "AssetGroupProductGroupView": "google.ads.googleads.v12.resources.types.asset_group_product_group_view", + "AssetGroupSignal": "google.ads.googleads.v12.resources.types.asset_group_signal", + "AssetPolicySummary": "google.ads.googleads.v12.resources.types.asset", + "AssetSet": "google.ads.googleads.v12.resources.types.asset_set", + "AssetSetAsset": "google.ads.googleads.v12.resources.types.asset_set_asset", + "AssetSetTypeView": "google.ads.googleads.v12.resources.types.asset_set_type_view", + "AttributeFieldMapping": "google.ads.googleads.v12.resources.types.feed_mapping", + "Audience": "google.ads.googleads.v12.resources.types.audience", + "BatchJob": "google.ads.googleads.v12.resources.types.batch_job", + "BiddingDataExclusion": "google.ads.googleads.v12.resources.types.bidding_data_exclusion", + "BiddingSeasonalityAdjustment": "google.ads.googleads.v12.resources.types.bidding_seasonality_adjustment", + "BiddingStrategy": "google.ads.googleads.v12.resources.types.bidding_strategy", + "BiddingStrategySimulation": "google.ads.googleads.v12.resources.types.bidding_strategy_simulation", + "BillingSetup": "google.ads.googleads.v12.resources.types.billing_setup", + "CallReportingSetting": "google.ads.googleads.v12.resources.types.customer", + "CallView": "google.ads.googleads.v12.resources.types.call_view", + "Campaign": "google.ads.googleads.v12.resources.types.campaign", + "CampaignAsset": "google.ads.googleads.v12.resources.types.campaign_asset", + "CampaignAssetSet": "google.ads.googleads.v12.resources.types.campaign_asset_set", + "CampaignAudienceView": "google.ads.googleads.v12.resources.types.campaign_audience_view", + "CampaignBidModifier": "google.ads.googleads.v12.resources.types.campaign_bid_modifier", + "CampaignBudget": "google.ads.googleads.v12.resources.types.campaign_budget", + "CampaignConversionGoal": "google.ads.googleads.v12.resources.types.campaign_conversion_goal", + "CampaignCriterion": "google.ads.googleads.v12.resources.types.campaign_criterion", + "CampaignCriterionSimulation": "google.ads.googleads.v12.resources.types.campaign_criterion_simulation", + "CampaignCustomizer": "google.ads.googleads.v12.resources.types.campaign_customizer", + "CampaignDraft": "google.ads.googleads.v12.resources.types.campaign_draft", + "CampaignExtensionSetting": "google.ads.googleads.v12.resources.types.campaign_extension_setting", + "CampaignFeed": "google.ads.googleads.v12.resources.types.campaign_feed", + "CampaignGroup": "google.ads.googleads.v12.resources.types.campaign_group", + "CampaignLabel": "google.ads.googleads.v12.resources.types.campaign_label", + "CampaignSharedSet": "google.ads.googleads.v12.resources.types.campaign_shared_set", + "CampaignSimulation": "google.ads.googleads.v12.resources.types.campaign_simulation", + "CarrierConstant": "google.ads.googleads.v12.resources.types.carrier_constant", + "ChangeEvent": "google.ads.googleads.v12.resources.types.change_event", + "ChangeStatus": "google.ads.googleads.v12.resources.types.change_status", + "ClickView": "google.ads.googleads.v12.resources.types.click_view", + "CombinedAudience": "google.ads.googleads.v12.resources.types.combined_audience", + "ConversionAction": "google.ads.googleads.v12.resources.types.conversion_action", + "ConversionCustomVariable": "google.ads.googleads.v12.resources.types.conversion_custom_variable", + "ConversionGoalCampaignConfig": "google.ads.googleads.v12.resources.types.conversion_goal_campaign_config", + "ConversionTrackingSetting": "google.ads.googleads.v12.resources.types.customer", + "ConversionValueRule": "google.ads.googleads.v12.resources.types.conversion_value_rule", + "ConversionValueRuleSet": "google.ads.googleads.v12.resources.types.conversion_value_rule_set", + "CurrencyConstant": "google.ads.googleads.v12.resources.types.currency_constant", + "CustomAudience": "google.ads.googleads.v12.resources.types.custom_audience", + "CustomAudienceMember": "google.ads.googleads.v12.resources.types.custom_audience", + "CustomConversionGoal": "google.ads.googleads.v12.resources.types.custom_conversion_goal", + "Customer": "google.ads.googleads.v12.resources.types.customer", + "CustomerAsset": "google.ads.googleads.v12.resources.types.customer_asset", + "CustomerAssetSet": "google.ads.googleads.v12.resources.types.customer_asset_set", + "CustomerClient": "google.ads.googleads.v12.resources.types.customer_client", + "CustomerClientLink": "google.ads.googleads.v12.resources.types.customer_client_link", + "CustomerConversionGoal": "google.ads.googleads.v12.resources.types.customer_conversion_goal", + "CustomerCustomizer": "google.ads.googleads.v12.resources.types.customer_customizer", + "CustomerExtensionSetting": "google.ads.googleads.v12.resources.types.customer_extension_setting", + "CustomerFeed": "google.ads.googleads.v12.resources.types.customer_feed", + "CustomerLabel": "google.ads.googleads.v12.resources.types.customer_label", + "CustomerManagerLink": "google.ads.googleads.v12.resources.types.customer_manager_link", + "CustomerNegativeCriterion": "google.ads.googleads.v12.resources.types.customer_negative_criterion", + "CustomerUserAccess": "google.ads.googleads.v12.resources.types.customer_user_access", + "CustomerUserAccessInvitation": "google.ads.googleads.v12.resources.types.customer_user_access_invitation", + "CustomInterest": "google.ads.googleads.v12.resources.types.custom_interest", + "CustomInterestMember": "google.ads.googleads.v12.resources.types.custom_interest", + "CustomizerAttribute": "google.ads.googleads.v12.resources.types.customizer_attribute", + "CustomLeadFormSubmissionField": "google.ads.googleads.v12.resources.types.lead_form_submission_data", + "DataPartnerLinkIdentifier": "google.ads.googleads.v12.resources.types.account_link", + "DetailedDemographic": "google.ads.googleads.v12.resources.types.detailed_demographic", + "DetailPlacementView": "google.ads.googleads.v12.resources.types.detail_placement_view", + "DisplayKeywordView": "google.ads.googleads.v12.resources.types.display_keyword_view", + "DistanceView": "google.ads.googleads.v12.resources.types.distance_view", + "DomainCategory": "google.ads.googleads.v12.resources.types.domain_category", + "DynamicSearchAdsSearchTermView": "google.ads.googleads.v12.resources.types.dynamic_search_ads_search_term_view", + "ExpandedLandingPageView": "google.ads.googleads.v12.resources.types.expanded_landing_page_view", + "Experiment": "google.ads.googleads.v12.resources.types.experiment", + "ExperimentArm": "google.ads.googleads.v12.resources.types.experiment_arm", + "ExtensionFeedItem": "google.ads.googleads.v12.resources.types.extension_feed_item", + "Feed": "google.ads.googleads.v12.resources.types.feed", + "FeedAttribute": "google.ads.googleads.v12.resources.types.feed", + "FeedAttributeOperation": "google.ads.googleads.v12.resources.types.feed", + "FeedItem": "google.ads.googleads.v12.resources.types.feed_item", + "FeedItemAttributeValue": "google.ads.googleads.v12.resources.types.feed_item", + "FeedItemPlaceholderPolicyInfo": "google.ads.googleads.v12.resources.types.feed_item", + "FeedItemSet": "google.ads.googleads.v12.resources.types.feed_item_set", + "FeedItemSetLink": "google.ads.googleads.v12.resources.types.feed_item_set_link", + "FeedItemTarget": "google.ads.googleads.v12.resources.types.feed_item_target", + "FeedItemValidationError": "google.ads.googleads.v12.resources.types.feed_item", + "FeedMapping": "google.ads.googleads.v12.resources.types.feed_mapping", + "FeedPlaceholderView": "google.ads.googleads.v12.resources.types.feed_placeholder_view", + "GenderView": "google.ads.googleads.v12.resources.types.gender_view", + "GeographicView": "google.ads.googleads.v12.resources.types.geographic_view", + "GeoTargetConstant": "google.ads.googleads.v12.resources.types.geo_target_constant", + "GoogleAdsField": "google.ads.googleads.v12.resources.types.google_ads_field", + "GoogleAdsLinkIdentifier": "google.ads.googleads.v12.resources.types.account_link", + "GroupPlacementView": "google.ads.googleads.v12.resources.types.group_placement_view", + "HotelCenterLinkIdentifier": "google.ads.googleads.v12.resources.types.account_link", + "HotelGroupView": "google.ads.googleads.v12.resources.types.hotel_group_view", + "HotelPerformanceView": "google.ads.googleads.v12.resources.types.hotel_performance_view", + "HotelReconciliation": "google.ads.googleads.v12.resources.types.hotel_reconciliation", + "IncomeRangeView": "google.ads.googleads.v12.resources.types.income_range_view", + "Invoice": "google.ads.googleads.v12.resources.types.invoice", + "KeywordPlan": "google.ads.googleads.v12.resources.types.keyword_plan", + "KeywordPlanAdGroup": "google.ads.googleads.v12.resources.types.keyword_plan_ad_group", + "KeywordPlanAdGroupKeyword": "google.ads.googleads.v12.resources.types.keyword_plan_ad_group_keyword", + "KeywordPlanCampaign": "google.ads.googleads.v12.resources.types.keyword_plan_campaign", + "KeywordPlanCampaignKeyword": "google.ads.googleads.v12.resources.types.keyword_plan_campaign_keyword", + "KeywordPlanForecastPeriod": "google.ads.googleads.v12.resources.types.keyword_plan", + "KeywordPlanGeoTarget": "google.ads.googleads.v12.resources.types.keyword_plan_campaign", + "KeywordThemeConstant": "google.ads.googleads.v12.resources.types.keyword_theme_constant", + "KeywordView": "google.ads.googleads.v12.resources.types.keyword_view", + "Label": "google.ads.googleads.v12.resources.types.label", + "LandingPageView": "google.ads.googleads.v12.resources.types.landing_page_view", + "LanguageConstant": "google.ads.googleads.v12.resources.types.language_constant", + "LeadFormSubmissionData": "google.ads.googleads.v12.resources.types.lead_form_submission_data", + "LeadFormSubmissionField": "google.ads.googleads.v12.resources.types.lead_form_submission_data", + "LifeEvent": "google.ads.googleads.v12.resources.types.life_event", + "ListingGroupFilterDimension": "google.ads.googleads.v12.resources.types.asset_group_listing_group_filter", + "LocationView": "google.ads.googleads.v12.resources.types.location_view", + "ManagedPlacementView": "google.ads.googleads.v12.resources.types.managed_placement_view", + "MediaAudio": "google.ads.googleads.v12.resources.types.media_file", + "MediaBundle": "google.ads.googleads.v12.resources.types.media_file", + "MediaFile": "google.ads.googleads.v12.resources.types.media_file", + "MediaImage": "google.ads.googleads.v12.resources.types.media_file", + "MediaVideo": "google.ads.googleads.v12.resources.types.media_file", + "MerchantCenterLink": "google.ads.googleads.v12.resources.types.merchant_center_link", + "MobileAppCategoryConstant": "google.ads.googleads.v12.resources.types.mobile_app_category_constant", + "MobileDeviceConstant": "google.ads.googleads.v12.resources.types.mobile_device_constant", + "OfflineUserDataJob": "google.ads.googleads.v12.resources.types.offline_user_data_job", + "OfflineUserDataJobMetadata": "google.ads.googleads.v12.resources.types.offline_user_data_job", + "OperatingSystemVersionConstant": "google.ads.googleads.v12.resources.types.operating_system_version_constant", + "PaidOrganicSearchTermView": "google.ads.googleads.v12.resources.types.paid_organic_search_term_view", + "ParentalStatusView": "google.ads.googleads.v12.resources.types.parental_status_view", + "PaymentsAccount": "google.ads.googleads.v12.resources.types.payments_account", + "PerStoreView": "google.ads.googleads.v12.resources.types.per_store_view", + "ProductBiddingCategoryConstant": "google.ads.googleads.v12.resources.types.product_bidding_category_constant", + "ProductGroupView": "google.ads.googleads.v12.resources.types.product_group_view", + "Recommendation": "google.ads.googleads.v12.resources.types.recommendation", + "RemarketingAction": "google.ads.googleads.v12.resources.types.remarketing_action", + "RemarketingSetting": "google.ads.googleads.v12.resources.types.customer", + "SearchTermView": "google.ads.googleads.v12.resources.types.search_term_view", + "SharedCriterion": "google.ads.googleads.v12.resources.types.shared_criterion", + "SharedSet": "google.ads.googleads.v12.resources.types.shared_set", + "ShoppingPerformanceView": "google.ads.googleads.v12.resources.types.shopping_performance_view", + "SmartCampaignSearchTermView": "google.ads.googleads.v12.resources.types.smart_campaign_search_term_view", + "SmartCampaignSetting": "google.ads.googleads.v12.resources.types.smart_campaign_setting", + "ThirdPartyAppAnalyticsLink": "google.ads.googleads.v12.resources.types.third_party_app_analytics_link", + "ThirdPartyAppAnalyticsLinkIdentifier": "google.ads.googleads.v12.resources.types.account_link", + "TopicConstant": "google.ads.googleads.v12.resources.types.topic_constant", + "TopicView": "google.ads.googleads.v12.resources.types.topic_view", + "UserInterest": "google.ads.googleads.v12.resources.types.user_interest", + "UserList": "google.ads.googleads.v12.resources.types.user_list", + "UserLocationView": "google.ads.googleads.v12.resources.types.user_location_view", + "Video": "google.ads.googleads.v12.resources.types.video", + "WebpageView": "google.ads.googleads.v12.resources.types.webpage_view", + "AccountBudgetProposalOperation": "google.ads.googleads.v12.services.types.account_budget_proposal_service", + "AccountLinkOperation": "google.ads.googleads.v12.services.types.account_link_service", + "AddBatchJobOperationsRequest": "google.ads.googleads.v12.services.types.batch_job_service", + "AddBatchJobOperationsResponse": "google.ads.googleads.v12.services.types.batch_job_service", + "AddOfflineUserDataJobOperationsRequest": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "AddOfflineUserDataJobOperationsResponse": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "AdGroupAdLabelOperation": "google.ads.googleads.v12.services.types.ad_group_ad_label_service", + "AdGroupAdOperation": "google.ads.googleads.v12.services.types.ad_group_ad_service", + "AdGroupAssetOperation": "google.ads.googleads.v12.services.types.ad_group_asset_service", + "AdGroupAssetSetOperation": "google.ads.googleads.v12.services.types.ad_group_asset_set_service", + "AdGroupBidModifierOperation": "google.ads.googleads.v12.services.types.ad_group_bid_modifier_service", + "AdGroupCriterionCustomizerOperation": "google.ads.googleads.v12.services.types.ad_group_criterion_customizer_service", + "AdGroupCriterionLabelOperation": "google.ads.googleads.v12.services.types.ad_group_criterion_label_service", + "AdGroupCriterionOperation": "google.ads.googleads.v12.services.types.ad_group_criterion_service", + "AdGroupCustomizerOperation": "google.ads.googleads.v12.services.types.ad_group_customizer_service", + "AdGroupExtensionSettingOperation": "google.ads.googleads.v12.services.types.ad_group_extension_setting_service", + "AdGroupFeedOperation": "google.ads.googleads.v12.services.types.ad_group_feed_service", + "AdGroupKeywordSuggestion": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "AdGroupLabelOperation": "google.ads.googleads.v12.services.types.ad_group_label_service", + "AdGroupOperation": "google.ads.googleads.v12.services.types.ad_group_service", + "AdOperation": "google.ads.googleads.v12.services.types.ad_service", + "AdParameterOperation": "google.ads.googleads.v12.services.types.ad_parameter_service", + "AdvancedProductTargeting": "google.ads.googleads.v12.services.types.reach_plan_service", + "ApplyRecommendationOperation": "google.ads.googleads.v12.services.types.recommendation_service", + "ApplyRecommendationRequest": "google.ads.googleads.v12.services.types.recommendation_service", + "ApplyRecommendationResponse": "google.ads.googleads.v12.services.types.recommendation_service", + "ApplyRecommendationResult": "google.ads.googleads.v12.services.types.recommendation_service", + "AssetGroupAssetOperation": "google.ads.googleads.v12.services.types.asset_group_asset_service", + "AssetGroupListingGroupFilterOperation": "google.ads.googleads.v12.services.types.asset_group_listing_group_filter_service", + "AssetGroupOperation": "google.ads.googleads.v12.services.types.asset_group_service", + "AssetGroupSignalOperation": "google.ads.googleads.v12.services.types.asset_group_signal_service", + "AssetOperation": "google.ads.googleads.v12.services.types.asset_service", + "AssetSetAssetOperation": "google.ads.googleads.v12.services.types.asset_set_asset_service", + "AssetSetOperation": "google.ads.googleads.v12.services.types.asset_set_service", + "AudienceCompositionAttribute": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceCompositionAttributeCluster": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceCompositionMetrics": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceCompositionSection": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsAttribute": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsAttributeMetadata": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsCategory": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsDynamicLineup": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsEntity": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceInsightsTopic": "google.ads.googleads.v12.services.types.audience_insights_service", + "AudienceOperation": "google.ads.googleads.v12.services.types.audience_service", + "AudienceTargeting": "google.ads.googleads.v12.services.types.reach_plan_service", + "BasicInsightsAudience": "google.ads.googleads.v12.services.types.audience_insights_service", + "BatchJobOperation": "google.ads.googleads.v12.services.types.batch_job_service", + "BatchJobResult": "google.ads.googleads.v12.services.types.batch_job_service", + "BiddingDataExclusionOperation": "google.ads.googleads.v12.services.types.bidding_data_exclusion_service", + "BiddingSeasonalityAdjustmentOperation": "google.ads.googleads.v12.services.types.bidding_seasonality_adjustment_service", + "BiddingStrategyOperation": "google.ads.googleads.v12.services.types.bidding_strategy_service", + "BillingSetupOperation": "google.ads.googleads.v12.services.types.billing_setup_service", + "CallConversion": "google.ads.googleads.v12.services.types.conversion_upload_service", + "CallConversionResult": "google.ads.googleads.v12.services.types.conversion_upload_service", + "CampaignAssetOperation": "google.ads.googleads.v12.services.types.campaign_asset_service", + "CampaignAssetSetOperation": "google.ads.googleads.v12.services.types.campaign_asset_set_service", + "CampaignBidModifierOperation": "google.ads.googleads.v12.services.types.campaign_bid_modifier_service", + "CampaignBudgetMapping": "google.ads.googleads.v12.services.types.experiment_service", + "CampaignBudgetOperation": "google.ads.googleads.v12.services.types.campaign_budget_service", + "CampaignConversionGoalOperation": "google.ads.googleads.v12.services.types.campaign_conversion_goal_service", + "CampaignCriterionOperation": "google.ads.googleads.v12.services.types.campaign_criterion_service", + "CampaignCustomizerOperation": "google.ads.googleads.v12.services.types.campaign_customizer_service", + "CampaignDraftOperation": "google.ads.googleads.v12.services.types.campaign_draft_service", + "CampaignDuration": "google.ads.googleads.v12.services.types.reach_plan_service", + "CampaignExtensionSettingOperation": "google.ads.googleads.v12.services.types.campaign_extension_setting_service", + "CampaignFeedOperation": "google.ads.googleads.v12.services.types.campaign_feed_service", + "CampaignGroupOperation": "google.ads.googleads.v12.services.types.campaign_group_service", + "CampaignLabelOperation": "google.ads.googleads.v12.services.types.campaign_label_service", + "CampaignOperation": "google.ads.googleads.v12.services.types.campaign_service", + "CampaignSharedSetOperation": "google.ads.googleads.v12.services.types.campaign_shared_set_service", + "CartData": "google.ads.googleads.v12.services.types.conversion_upload_service", + "ClickConversion": "google.ads.googleads.v12.services.types.conversion_upload_service", + "ClickConversionResult": "google.ads.googleads.v12.services.types.conversion_upload_service", + "ConversionActionOperation": "google.ads.googleads.v12.services.types.conversion_action_service", + "ConversionAdjustment": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "ConversionAdjustmentResult": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "ConversionCustomVariableOperation": "google.ads.googleads.v12.services.types.conversion_custom_variable_service", + "ConversionGoalCampaignConfigOperation": "google.ads.googleads.v12.services.types.conversion_goal_campaign_config_service", + "ConversionValueRuleOperation": "google.ads.googleads.v12.services.types.conversion_value_rule_service", + "ConversionValueRuleSetOperation": "google.ads.googleads.v12.services.types.conversion_value_rule_set_service", + "CreateAccountLinkRequest": "google.ads.googleads.v12.services.types.account_link_service", + "CreateAccountLinkResponse": "google.ads.googleads.v12.services.types.account_link_service", + "CreateCustomerClientRequest": "google.ads.googleads.v12.services.types.customer_service", + "CreateCustomerClientResponse": "google.ads.googleads.v12.services.types.customer_service", + "CreateOfflineUserDataJobRequest": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "CreateOfflineUserDataJobResponse": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "CustomAudienceOperation": "google.ads.googleads.v12.services.types.custom_audience_service", + "CustomConversionGoalOperation": "google.ads.googleads.v12.services.types.custom_conversion_goal_service", + "CustomerAssetOperation": "google.ads.googleads.v12.services.types.customer_asset_service", + "CustomerAssetSetOperation": "google.ads.googleads.v12.services.types.customer_asset_set_service", + "CustomerClientLinkOperation": "google.ads.googleads.v12.services.types.customer_client_link_service", + "CustomerConversionGoalOperation": "google.ads.googleads.v12.services.types.customer_conversion_goal_service", + "CustomerCustomizerOperation": "google.ads.googleads.v12.services.types.customer_customizer_service", + "CustomerExtensionSettingOperation": "google.ads.googleads.v12.services.types.customer_extension_setting_service", + "CustomerFeedOperation": "google.ads.googleads.v12.services.types.customer_feed_service", + "CustomerLabelOperation": "google.ads.googleads.v12.services.types.customer_label_service", + "CustomerManagerLinkOperation": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "CustomerNegativeCriterionOperation": "google.ads.googleads.v12.services.types.customer_negative_criterion_service", + "CustomerOperation": "google.ads.googleads.v12.services.types.customer_service", + "CustomerUserAccessInvitationOperation": "google.ads.googleads.v12.services.types.customer_user_access_invitation_service", + "CustomerUserAccessOperation": "google.ads.googleads.v12.services.types.customer_user_access_service", + "CustomInterestOperation": "google.ads.googleads.v12.services.types.custom_interest_service", + "CustomizerAttributeOperation": "google.ads.googleads.v12.services.types.customizer_attribute_service", + "CustomVariable": "google.ads.googleads.v12.services.types.conversion_upload_service", + "DismissRecommendationRequest": "google.ads.googleads.v12.services.types.recommendation_service", + "DismissRecommendationResponse": "google.ads.googleads.v12.services.types.recommendation_service", + "DynamicLineupAttributeMetadata": "google.ads.googleads.v12.services.types.audience_insights_service", + "EffectiveFrequencyBreakdown": "google.ads.googleads.v12.services.types.reach_plan_service", + "EffectiveFrequencyLimit": "google.ads.googleads.v12.services.types.reach_plan_service", + "EndExperimentRequest": "google.ads.googleads.v12.services.types.experiment_service", + "ExperimentArmOperation": "google.ads.googleads.v12.services.types.experiment_arm_service", + "ExperimentOperation": "google.ads.googleads.v12.services.types.experiment_service", + "ExtensionFeedItemOperation": "google.ads.googleads.v12.services.types.extension_feed_item_service", + "ExternalAttributionData": "google.ads.googleads.v12.services.types.conversion_upload_service", + "FeedItemOperation": "google.ads.googleads.v12.services.types.feed_item_service", + "FeedItemSetLinkOperation": "google.ads.googleads.v12.services.types.feed_item_set_link_service", + "FeedItemSetOperation": "google.ads.googleads.v12.services.types.feed_item_set_service", + "FeedItemTargetOperation": "google.ads.googleads.v12.services.types.feed_item_target_service", + "FeedMappingOperation": "google.ads.googleads.v12.services.types.feed_mapping_service", + "FeedOperation": "google.ads.googleads.v12.services.types.feed_service", + "Forecast": "google.ads.googleads.v12.services.types.reach_plan_service", + "ForecastMetricOptions": "google.ads.googleads.v12.services.types.reach_plan_service", + "ForecastMetrics": "google.ads.googleads.v12.services.types.keyword_plan_service", + "FrequencyCap": "google.ads.googleads.v12.services.types.reach_plan_service", + "GclidDateTimePair": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "GenerateAdGroupThemesRequest": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateAdGroupThemesResponse": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateAudienceCompositionInsightsRequest": "google.ads.googleads.v12.services.types.audience_insights_service", + "GenerateAudienceCompositionInsightsResponse": "google.ads.googleads.v12.services.types.audience_insights_service", + "GenerateForecastCurveRequest": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateForecastCurveResponse": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateForecastMetricsRequest": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateForecastMetricsResponse": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateForecastTimeSeriesRequest": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateForecastTimeSeriesResponse": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateHistoricalMetricsRequest": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateHistoricalMetricsResponse": "google.ads.googleads.v12.services.types.keyword_plan_service", + "GenerateInsightsFinderReportRequest": "google.ads.googleads.v12.services.types.audience_insights_service", + "GenerateInsightsFinderReportResponse": "google.ads.googleads.v12.services.types.audience_insights_service", + "GenerateKeywordHistoricalMetricsRequest": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateKeywordHistoricalMetricsResponse": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateKeywordHistoricalMetricsResult": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateKeywordIdeaResponse": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateKeywordIdeaResult": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateKeywordIdeasRequest": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "GenerateReachForecastRequest": "google.ads.googleads.v12.services.types.reach_plan_service", + "GenerateReachForecastResponse": "google.ads.googleads.v12.services.types.reach_plan_service", + "GeoTargetConstantSuggestion": "google.ads.googleads.v12.services.types.geo_target_constant_service", + "GetAdRequest": "google.ads.googleads.v12.services.types.ad_service", + "GetGoogleAdsFieldRequest": "google.ads.googleads.v12.services.types.google_ads_field_service", + "GetMerchantCenterLinkRequest": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "GoogleAdsRow": "google.ads.googleads.v12.services.types.google_ads_service", + "GraduateExperimentRequest": "google.ads.googleads.v12.services.types.experiment_service", + "InsightsAudience": "google.ads.googleads.v12.services.types.audience_insights_service", + "InsightsAudienceAttributeGroup": "google.ads.googleads.v12.services.types.audience_insights_service", + "KeywordAndUrlSeed": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "KeywordPlanAdGroupForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanAdGroupKeywordOperation": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_keyword_service", + "KeywordPlanAdGroupOperation": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_service", + "KeywordPlanCampaignForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanCampaignForecastCurve": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanCampaignKeywordOperation": "google.ads.googleads.v12.services.types.keyword_plan_campaign_keyword_service", + "KeywordPlanCampaignOperation": "google.ads.googleads.v12.services.types.keyword_plan_campaign_service", + "KeywordPlanKeywordForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanKeywordHistoricalMetrics": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanMaxCpcBidForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanMaxCpcBidForecastCurve": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanOperation": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanWeeklyForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordPlanWeeklyTimeSeriesForecast": "google.ads.googleads.v12.services.types.keyword_plan_service", + "KeywordSeed": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "LabelOperation": "google.ads.googleads.v12.services.types.label_service", + "ListAccessibleCustomersRequest": "google.ads.googleads.v12.services.types.customer_service", + "ListAccessibleCustomersResponse": "google.ads.googleads.v12.services.types.customer_service", + "ListAudienceInsightsAttributesRequest": "google.ads.googleads.v12.services.types.audience_insights_service", + "ListAudienceInsightsAttributesResponse": "google.ads.googleads.v12.services.types.audience_insights_service", + "ListBatchJobResultsRequest": "google.ads.googleads.v12.services.types.batch_job_service", + "ListBatchJobResultsResponse": "google.ads.googleads.v12.services.types.batch_job_service", + "ListCampaignDraftAsyncErrorsRequest": "google.ads.googleads.v12.services.types.campaign_draft_service", + "ListCampaignDraftAsyncErrorsResponse": "google.ads.googleads.v12.services.types.campaign_draft_service", + "ListExperimentAsyncErrorsRequest": "google.ads.googleads.v12.services.types.experiment_service", + "ListExperimentAsyncErrorsResponse": "google.ads.googleads.v12.services.types.experiment_service", + "ListInsightsEligibleDatesRequest": "google.ads.googleads.v12.services.types.audience_insights_service", + "ListInsightsEligibleDatesResponse": "google.ads.googleads.v12.services.types.audience_insights_service", + "ListInvoicesRequest": "google.ads.googleads.v12.services.types.invoice_service", + "ListInvoicesResponse": "google.ads.googleads.v12.services.types.invoice_service", + "ListMerchantCenterLinksRequest": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "ListMerchantCenterLinksResponse": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "ListPaymentsAccountsRequest": "google.ads.googleads.v12.services.types.payments_account_service", + "ListPaymentsAccountsResponse": "google.ads.googleads.v12.services.types.payments_account_service", + "ListPlannableLocationsRequest": "google.ads.googleads.v12.services.types.reach_plan_service", + "ListPlannableLocationsResponse": "google.ads.googleads.v12.services.types.reach_plan_service", + "ListPlannableProductsRequest": "google.ads.googleads.v12.services.types.reach_plan_service", + "ListPlannableProductsResponse": "google.ads.googleads.v12.services.types.reach_plan_service", + "LocationAttributeMetadata": "google.ads.googleads.v12.services.types.audience_insights_service", + "MediaFileOperation": "google.ads.googleads.v12.services.types.media_file_service", + "MerchantCenterLinkOperation": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "MoveManagerLinkRequest": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "MoveManagerLinkResponse": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "MutateAccountBudgetProposalRequest": "google.ads.googleads.v12.services.types.account_budget_proposal_service", + "MutateAccountBudgetProposalResponse": "google.ads.googleads.v12.services.types.account_budget_proposal_service", + "MutateAccountBudgetProposalResult": "google.ads.googleads.v12.services.types.account_budget_proposal_service", + "MutateAccountLinkRequest": "google.ads.googleads.v12.services.types.account_link_service", + "MutateAccountLinkResponse": "google.ads.googleads.v12.services.types.account_link_service", + "MutateAccountLinkResult": "google.ads.googleads.v12.services.types.account_link_service", + "MutateAdGroupAdLabelResult": "google.ads.googleads.v12.services.types.ad_group_ad_label_service", + "MutateAdGroupAdLabelsRequest": "google.ads.googleads.v12.services.types.ad_group_ad_label_service", + "MutateAdGroupAdLabelsResponse": "google.ads.googleads.v12.services.types.ad_group_ad_label_service", + "MutateAdGroupAdResult": "google.ads.googleads.v12.services.types.ad_group_ad_service", + "MutateAdGroupAdsRequest": "google.ads.googleads.v12.services.types.ad_group_ad_service", + "MutateAdGroupAdsResponse": "google.ads.googleads.v12.services.types.ad_group_ad_service", + "MutateAdGroupAssetResult": "google.ads.googleads.v12.services.types.ad_group_asset_service", + "MutateAdGroupAssetSetResult": "google.ads.googleads.v12.services.types.ad_group_asset_set_service", + "MutateAdGroupAssetSetsRequest": "google.ads.googleads.v12.services.types.ad_group_asset_set_service", + "MutateAdGroupAssetSetsResponse": "google.ads.googleads.v12.services.types.ad_group_asset_set_service", + "MutateAdGroupAssetsRequest": "google.ads.googleads.v12.services.types.ad_group_asset_service", + "MutateAdGroupAssetsResponse": "google.ads.googleads.v12.services.types.ad_group_asset_service", + "MutateAdGroupBidModifierResult": "google.ads.googleads.v12.services.types.ad_group_bid_modifier_service", + "MutateAdGroupBidModifiersRequest": "google.ads.googleads.v12.services.types.ad_group_bid_modifier_service", + "MutateAdGroupBidModifiersResponse": "google.ads.googleads.v12.services.types.ad_group_bid_modifier_service", + "MutateAdGroupCriteriaRequest": "google.ads.googleads.v12.services.types.ad_group_criterion_service", + "MutateAdGroupCriteriaResponse": "google.ads.googleads.v12.services.types.ad_group_criterion_service", + "MutateAdGroupCriterionCustomizerResult": "google.ads.googleads.v12.services.types.ad_group_criterion_customizer_service", + "MutateAdGroupCriterionCustomizersRequest": "google.ads.googleads.v12.services.types.ad_group_criterion_customizer_service", + "MutateAdGroupCriterionCustomizersResponse": "google.ads.googleads.v12.services.types.ad_group_criterion_customizer_service", + "MutateAdGroupCriterionLabelResult": "google.ads.googleads.v12.services.types.ad_group_criterion_label_service", + "MutateAdGroupCriterionLabelsRequest": "google.ads.googleads.v12.services.types.ad_group_criterion_label_service", + "MutateAdGroupCriterionLabelsResponse": "google.ads.googleads.v12.services.types.ad_group_criterion_label_service", + "MutateAdGroupCriterionResult": "google.ads.googleads.v12.services.types.ad_group_criterion_service", + "MutateAdGroupCustomizerResult": "google.ads.googleads.v12.services.types.ad_group_customizer_service", + "MutateAdGroupCustomizersRequest": "google.ads.googleads.v12.services.types.ad_group_customizer_service", + "MutateAdGroupCustomizersResponse": "google.ads.googleads.v12.services.types.ad_group_customizer_service", + "MutateAdGroupExtensionSettingResult": "google.ads.googleads.v12.services.types.ad_group_extension_setting_service", + "MutateAdGroupExtensionSettingsRequest": "google.ads.googleads.v12.services.types.ad_group_extension_setting_service", + "MutateAdGroupExtensionSettingsResponse": "google.ads.googleads.v12.services.types.ad_group_extension_setting_service", + "MutateAdGroupFeedResult": "google.ads.googleads.v12.services.types.ad_group_feed_service", + "MutateAdGroupFeedsRequest": "google.ads.googleads.v12.services.types.ad_group_feed_service", + "MutateAdGroupFeedsResponse": "google.ads.googleads.v12.services.types.ad_group_feed_service", + "MutateAdGroupLabelResult": "google.ads.googleads.v12.services.types.ad_group_label_service", + "MutateAdGroupLabelsRequest": "google.ads.googleads.v12.services.types.ad_group_label_service", + "MutateAdGroupLabelsResponse": "google.ads.googleads.v12.services.types.ad_group_label_service", + "MutateAdGroupResult": "google.ads.googleads.v12.services.types.ad_group_service", + "MutateAdGroupsRequest": "google.ads.googleads.v12.services.types.ad_group_service", + "MutateAdGroupsResponse": "google.ads.googleads.v12.services.types.ad_group_service", + "MutateAdParameterResult": "google.ads.googleads.v12.services.types.ad_parameter_service", + "MutateAdParametersRequest": "google.ads.googleads.v12.services.types.ad_parameter_service", + "MutateAdParametersResponse": "google.ads.googleads.v12.services.types.ad_parameter_service", + "MutateAdResult": "google.ads.googleads.v12.services.types.ad_service", + "MutateAdsRequest": "google.ads.googleads.v12.services.types.ad_service", + "MutateAdsResponse": "google.ads.googleads.v12.services.types.ad_service", + "MutateAssetGroupAssetResult": "google.ads.googleads.v12.services.types.asset_group_asset_service", + "MutateAssetGroupAssetsRequest": "google.ads.googleads.v12.services.types.asset_group_asset_service", + "MutateAssetGroupAssetsResponse": "google.ads.googleads.v12.services.types.asset_group_asset_service", + "MutateAssetGroupListingGroupFilterResult": "google.ads.googleads.v12.services.types.asset_group_listing_group_filter_service", + "MutateAssetGroupListingGroupFiltersRequest": "google.ads.googleads.v12.services.types.asset_group_listing_group_filter_service", + "MutateAssetGroupListingGroupFiltersResponse": "google.ads.googleads.v12.services.types.asset_group_listing_group_filter_service", + "MutateAssetGroupResult": "google.ads.googleads.v12.services.types.asset_group_service", + "MutateAssetGroupSignalResult": "google.ads.googleads.v12.services.types.asset_group_signal_service", + "MutateAssetGroupSignalsRequest": "google.ads.googleads.v12.services.types.asset_group_signal_service", + "MutateAssetGroupSignalsResponse": "google.ads.googleads.v12.services.types.asset_group_signal_service", + "MutateAssetGroupsRequest": "google.ads.googleads.v12.services.types.asset_group_service", + "MutateAssetGroupsResponse": "google.ads.googleads.v12.services.types.asset_group_service", + "MutateAssetResult": "google.ads.googleads.v12.services.types.asset_service", + "MutateAssetSetAssetResult": "google.ads.googleads.v12.services.types.asset_set_asset_service", + "MutateAssetSetAssetsRequest": "google.ads.googleads.v12.services.types.asset_set_asset_service", + "MutateAssetSetAssetsResponse": "google.ads.googleads.v12.services.types.asset_set_asset_service", + "MutateAssetSetResult": "google.ads.googleads.v12.services.types.asset_set_service", + "MutateAssetSetsRequest": "google.ads.googleads.v12.services.types.asset_set_service", + "MutateAssetSetsResponse": "google.ads.googleads.v12.services.types.asset_set_service", + "MutateAssetsRequest": "google.ads.googleads.v12.services.types.asset_service", + "MutateAssetsResponse": "google.ads.googleads.v12.services.types.asset_service", + "MutateAudienceResult": "google.ads.googleads.v12.services.types.audience_service", + "MutateAudiencesRequest": "google.ads.googleads.v12.services.types.audience_service", + "MutateAudiencesResponse": "google.ads.googleads.v12.services.types.audience_service", + "MutateBatchJobRequest": "google.ads.googleads.v12.services.types.batch_job_service", + "MutateBatchJobResponse": "google.ads.googleads.v12.services.types.batch_job_service", + "MutateBatchJobResult": "google.ads.googleads.v12.services.types.batch_job_service", + "MutateBiddingDataExclusionsRequest": "google.ads.googleads.v12.services.types.bidding_data_exclusion_service", + "MutateBiddingDataExclusionsResponse": "google.ads.googleads.v12.services.types.bidding_data_exclusion_service", + "MutateBiddingDataExclusionsResult": "google.ads.googleads.v12.services.types.bidding_data_exclusion_service", + "MutateBiddingSeasonalityAdjustmentsRequest": "google.ads.googleads.v12.services.types.bidding_seasonality_adjustment_service", + "MutateBiddingSeasonalityAdjustmentsResponse": "google.ads.googleads.v12.services.types.bidding_seasonality_adjustment_service", + "MutateBiddingSeasonalityAdjustmentsResult": "google.ads.googleads.v12.services.types.bidding_seasonality_adjustment_service", + "MutateBiddingStrategiesRequest": "google.ads.googleads.v12.services.types.bidding_strategy_service", + "MutateBiddingStrategiesResponse": "google.ads.googleads.v12.services.types.bidding_strategy_service", + "MutateBiddingStrategyResult": "google.ads.googleads.v12.services.types.bidding_strategy_service", + "MutateBillingSetupRequest": "google.ads.googleads.v12.services.types.billing_setup_service", + "MutateBillingSetupResponse": "google.ads.googleads.v12.services.types.billing_setup_service", + "MutateBillingSetupResult": "google.ads.googleads.v12.services.types.billing_setup_service", + "MutateCampaignAssetResult": "google.ads.googleads.v12.services.types.campaign_asset_service", + "MutateCampaignAssetSetResult": "google.ads.googleads.v12.services.types.campaign_asset_set_service", + "MutateCampaignAssetSetsRequest": "google.ads.googleads.v12.services.types.campaign_asset_set_service", + "MutateCampaignAssetSetsResponse": "google.ads.googleads.v12.services.types.campaign_asset_set_service", + "MutateCampaignAssetsRequest": "google.ads.googleads.v12.services.types.campaign_asset_service", + "MutateCampaignAssetsResponse": "google.ads.googleads.v12.services.types.campaign_asset_service", + "MutateCampaignBidModifierResult": "google.ads.googleads.v12.services.types.campaign_bid_modifier_service", + "MutateCampaignBidModifiersRequest": "google.ads.googleads.v12.services.types.campaign_bid_modifier_service", + "MutateCampaignBidModifiersResponse": "google.ads.googleads.v12.services.types.campaign_bid_modifier_service", + "MutateCampaignBudgetResult": "google.ads.googleads.v12.services.types.campaign_budget_service", + "MutateCampaignBudgetsRequest": "google.ads.googleads.v12.services.types.campaign_budget_service", + "MutateCampaignBudgetsResponse": "google.ads.googleads.v12.services.types.campaign_budget_service", + "MutateCampaignConversionGoalResult": "google.ads.googleads.v12.services.types.campaign_conversion_goal_service", + "MutateCampaignConversionGoalsRequest": "google.ads.googleads.v12.services.types.campaign_conversion_goal_service", + "MutateCampaignConversionGoalsResponse": "google.ads.googleads.v12.services.types.campaign_conversion_goal_service", + "MutateCampaignCriteriaRequest": "google.ads.googleads.v12.services.types.campaign_criterion_service", + "MutateCampaignCriteriaResponse": "google.ads.googleads.v12.services.types.campaign_criterion_service", + "MutateCampaignCriterionResult": "google.ads.googleads.v12.services.types.campaign_criterion_service", + "MutateCampaignCustomizerResult": "google.ads.googleads.v12.services.types.campaign_customizer_service", + "MutateCampaignCustomizersRequest": "google.ads.googleads.v12.services.types.campaign_customizer_service", + "MutateCampaignCustomizersResponse": "google.ads.googleads.v12.services.types.campaign_customizer_service", + "MutateCampaignDraftResult": "google.ads.googleads.v12.services.types.campaign_draft_service", + "MutateCampaignDraftsRequest": "google.ads.googleads.v12.services.types.campaign_draft_service", + "MutateCampaignDraftsResponse": "google.ads.googleads.v12.services.types.campaign_draft_service", + "MutateCampaignExtensionSettingResult": "google.ads.googleads.v12.services.types.campaign_extension_setting_service", + "MutateCampaignExtensionSettingsRequest": "google.ads.googleads.v12.services.types.campaign_extension_setting_service", + "MutateCampaignExtensionSettingsResponse": "google.ads.googleads.v12.services.types.campaign_extension_setting_service", + "MutateCampaignFeedResult": "google.ads.googleads.v12.services.types.campaign_feed_service", + "MutateCampaignFeedsRequest": "google.ads.googleads.v12.services.types.campaign_feed_service", + "MutateCampaignFeedsResponse": "google.ads.googleads.v12.services.types.campaign_feed_service", + "MutateCampaignGroupResult": "google.ads.googleads.v12.services.types.campaign_group_service", + "MutateCampaignGroupsRequest": "google.ads.googleads.v12.services.types.campaign_group_service", + "MutateCampaignGroupsResponse": "google.ads.googleads.v12.services.types.campaign_group_service", + "MutateCampaignLabelResult": "google.ads.googleads.v12.services.types.campaign_label_service", + "MutateCampaignLabelsRequest": "google.ads.googleads.v12.services.types.campaign_label_service", + "MutateCampaignLabelsResponse": "google.ads.googleads.v12.services.types.campaign_label_service", + "MutateCampaignResult": "google.ads.googleads.v12.services.types.campaign_service", + "MutateCampaignSharedSetResult": "google.ads.googleads.v12.services.types.campaign_shared_set_service", + "MutateCampaignSharedSetsRequest": "google.ads.googleads.v12.services.types.campaign_shared_set_service", + "MutateCampaignSharedSetsResponse": "google.ads.googleads.v12.services.types.campaign_shared_set_service", + "MutateCampaignsRequest": "google.ads.googleads.v12.services.types.campaign_service", + "MutateCampaignsResponse": "google.ads.googleads.v12.services.types.campaign_service", + "MutateConversionActionResult": "google.ads.googleads.v12.services.types.conversion_action_service", + "MutateConversionActionsRequest": "google.ads.googleads.v12.services.types.conversion_action_service", + "MutateConversionActionsResponse": "google.ads.googleads.v12.services.types.conversion_action_service", + "MutateConversionCustomVariableResult": "google.ads.googleads.v12.services.types.conversion_custom_variable_service", + "MutateConversionCustomVariablesRequest": "google.ads.googleads.v12.services.types.conversion_custom_variable_service", + "MutateConversionCustomVariablesResponse": "google.ads.googleads.v12.services.types.conversion_custom_variable_service", + "MutateConversionGoalCampaignConfigResult": "google.ads.googleads.v12.services.types.conversion_goal_campaign_config_service", + "MutateConversionGoalCampaignConfigsRequest": "google.ads.googleads.v12.services.types.conversion_goal_campaign_config_service", + "MutateConversionGoalCampaignConfigsResponse": "google.ads.googleads.v12.services.types.conversion_goal_campaign_config_service", + "MutateConversionValueRuleResult": "google.ads.googleads.v12.services.types.conversion_value_rule_service", + "MutateConversionValueRuleSetResult": "google.ads.googleads.v12.services.types.conversion_value_rule_set_service", + "MutateConversionValueRuleSetsRequest": "google.ads.googleads.v12.services.types.conversion_value_rule_set_service", + "MutateConversionValueRuleSetsResponse": "google.ads.googleads.v12.services.types.conversion_value_rule_set_service", + "MutateConversionValueRulesRequest": "google.ads.googleads.v12.services.types.conversion_value_rule_service", + "MutateConversionValueRulesResponse": "google.ads.googleads.v12.services.types.conversion_value_rule_service", + "MutateCustomAudienceResult": "google.ads.googleads.v12.services.types.custom_audience_service", + "MutateCustomAudiencesRequest": "google.ads.googleads.v12.services.types.custom_audience_service", + "MutateCustomAudiencesResponse": "google.ads.googleads.v12.services.types.custom_audience_service", + "MutateCustomConversionGoalResult": "google.ads.googleads.v12.services.types.custom_conversion_goal_service", + "MutateCustomConversionGoalsRequest": "google.ads.googleads.v12.services.types.custom_conversion_goal_service", + "MutateCustomConversionGoalsResponse": "google.ads.googleads.v12.services.types.custom_conversion_goal_service", + "MutateCustomerAssetResult": "google.ads.googleads.v12.services.types.customer_asset_service", + "MutateCustomerAssetSetResult": "google.ads.googleads.v12.services.types.customer_asset_set_service", + "MutateCustomerAssetSetsRequest": "google.ads.googleads.v12.services.types.customer_asset_set_service", + "MutateCustomerAssetSetsResponse": "google.ads.googleads.v12.services.types.customer_asset_set_service", + "MutateCustomerAssetsRequest": "google.ads.googleads.v12.services.types.customer_asset_service", + "MutateCustomerAssetsResponse": "google.ads.googleads.v12.services.types.customer_asset_service", + "MutateCustomerClientLinkRequest": "google.ads.googleads.v12.services.types.customer_client_link_service", + "MutateCustomerClientLinkResponse": "google.ads.googleads.v12.services.types.customer_client_link_service", + "MutateCustomerClientLinkResult": "google.ads.googleads.v12.services.types.customer_client_link_service", + "MutateCustomerConversionGoalResult": "google.ads.googleads.v12.services.types.customer_conversion_goal_service", + "MutateCustomerConversionGoalsRequest": "google.ads.googleads.v12.services.types.customer_conversion_goal_service", + "MutateCustomerConversionGoalsResponse": "google.ads.googleads.v12.services.types.customer_conversion_goal_service", + "MutateCustomerCustomizerResult": "google.ads.googleads.v12.services.types.customer_customizer_service", + "MutateCustomerCustomizersRequest": "google.ads.googleads.v12.services.types.customer_customizer_service", + "MutateCustomerCustomizersResponse": "google.ads.googleads.v12.services.types.customer_customizer_service", + "MutateCustomerExtensionSettingResult": "google.ads.googleads.v12.services.types.customer_extension_setting_service", + "MutateCustomerExtensionSettingsRequest": "google.ads.googleads.v12.services.types.customer_extension_setting_service", + "MutateCustomerExtensionSettingsResponse": "google.ads.googleads.v12.services.types.customer_extension_setting_service", + "MutateCustomerFeedResult": "google.ads.googleads.v12.services.types.customer_feed_service", + "MutateCustomerFeedsRequest": "google.ads.googleads.v12.services.types.customer_feed_service", + "MutateCustomerFeedsResponse": "google.ads.googleads.v12.services.types.customer_feed_service", + "MutateCustomerLabelResult": "google.ads.googleads.v12.services.types.customer_label_service", + "MutateCustomerLabelsRequest": "google.ads.googleads.v12.services.types.customer_label_service", + "MutateCustomerLabelsResponse": "google.ads.googleads.v12.services.types.customer_label_service", + "MutateCustomerManagerLinkRequest": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "MutateCustomerManagerLinkResponse": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "MutateCustomerManagerLinkResult": "google.ads.googleads.v12.services.types.customer_manager_link_service", + "MutateCustomerNegativeCriteriaRequest": "google.ads.googleads.v12.services.types.customer_negative_criterion_service", + "MutateCustomerNegativeCriteriaResponse": "google.ads.googleads.v12.services.types.customer_negative_criterion_service", + "MutateCustomerNegativeCriteriaResult": "google.ads.googleads.v12.services.types.customer_negative_criterion_service", + "MutateCustomerRequest": "google.ads.googleads.v12.services.types.customer_service", + "MutateCustomerResponse": "google.ads.googleads.v12.services.types.customer_service", + "MutateCustomerResult": "google.ads.googleads.v12.services.types.customer_service", + "MutateCustomerUserAccessInvitationRequest": "google.ads.googleads.v12.services.types.customer_user_access_invitation_service", + "MutateCustomerUserAccessInvitationResponse": "google.ads.googleads.v12.services.types.customer_user_access_invitation_service", + "MutateCustomerUserAccessInvitationResult": "google.ads.googleads.v12.services.types.customer_user_access_invitation_service", + "MutateCustomerUserAccessRequest": "google.ads.googleads.v12.services.types.customer_user_access_service", + "MutateCustomerUserAccessResponse": "google.ads.googleads.v12.services.types.customer_user_access_service", + "MutateCustomerUserAccessResult": "google.ads.googleads.v12.services.types.customer_user_access_service", + "MutateCustomInterestResult": "google.ads.googleads.v12.services.types.custom_interest_service", + "MutateCustomInterestsRequest": "google.ads.googleads.v12.services.types.custom_interest_service", + "MutateCustomInterestsResponse": "google.ads.googleads.v12.services.types.custom_interest_service", + "MutateCustomizerAttributeResult": "google.ads.googleads.v12.services.types.customizer_attribute_service", + "MutateCustomizerAttributesRequest": "google.ads.googleads.v12.services.types.customizer_attribute_service", + "MutateCustomizerAttributesResponse": "google.ads.googleads.v12.services.types.customizer_attribute_service", + "MutateExperimentArmResult": "google.ads.googleads.v12.services.types.experiment_arm_service", + "MutateExperimentArmsRequest": "google.ads.googleads.v12.services.types.experiment_arm_service", + "MutateExperimentArmsResponse": "google.ads.googleads.v12.services.types.experiment_arm_service", + "MutateExperimentResult": "google.ads.googleads.v12.services.types.experiment_service", + "MutateExperimentsRequest": "google.ads.googleads.v12.services.types.experiment_service", + "MutateExperimentsResponse": "google.ads.googleads.v12.services.types.experiment_service", + "MutateExtensionFeedItemResult": "google.ads.googleads.v12.services.types.extension_feed_item_service", + "MutateExtensionFeedItemsRequest": "google.ads.googleads.v12.services.types.extension_feed_item_service", + "MutateExtensionFeedItemsResponse": "google.ads.googleads.v12.services.types.extension_feed_item_service", + "MutateFeedItemResult": "google.ads.googleads.v12.services.types.feed_item_service", + "MutateFeedItemSetLinkResult": "google.ads.googleads.v12.services.types.feed_item_set_link_service", + "MutateFeedItemSetLinksRequest": "google.ads.googleads.v12.services.types.feed_item_set_link_service", + "MutateFeedItemSetLinksResponse": "google.ads.googleads.v12.services.types.feed_item_set_link_service", + "MutateFeedItemSetResult": "google.ads.googleads.v12.services.types.feed_item_set_service", + "MutateFeedItemSetsRequest": "google.ads.googleads.v12.services.types.feed_item_set_service", + "MutateFeedItemSetsResponse": "google.ads.googleads.v12.services.types.feed_item_set_service", + "MutateFeedItemsRequest": "google.ads.googleads.v12.services.types.feed_item_service", + "MutateFeedItemsResponse": "google.ads.googleads.v12.services.types.feed_item_service", + "MutateFeedItemTargetResult": "google.ads.googleads.v12.services.types.feed_item_target_service", + "MutateFeedItemTargetsRequest": "google.ads.googleads.v12.services.types.feed_item_target_service", + "MutateFeedItemTargetsResponse": "google.ads.googleads.v12.services.types.feed_item_target_service", + "MutateFeedMappingResult": "google.ads.googleads.v12.services.types.feed_mapping_service", + "MutateFeedMappingsRequest": "google.ads.googleads.v12.services.types.feed_mapping_service", + "MutateFeedMappingsResponse": "google.ads.googleads.v12.services.types.feed_mapping_service", + "MutateFeedResult": "google.ads.googleads.v12.services.types.feed_service", + "MutateFeedsRequest": "google.ads.googleads.v12.services.types.feed_service", + "MutateFeedsResponse": "google.ads.googleads.v12.services.types.feed_service", + "MutateGoogleAdsRequest": "google.ads.googleads.v12.services.types.google_ads_service", + "MutateGoogleAdsResponse": "google.ads.googleads.v12.services.types.google_ads_service", + "MutateKeywordPlanAdGroupKeywordResult": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_keyword_service", + "MutateKeywordPlanAdGroupKeywordsRequest": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_keyword_service", + "MutateKeywordPlanAdGroupKeywordsResponse": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_keyword_service", + "MutateKeywordPlanAdGroupResult": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_service", + "MutateKeywordPlanAdGroupsRequest": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_service", + "MutateKeywordPlanAdGroupsResponse": "google.ads.googleads.v12.services.types.keyword_plan_ad_group_service", + "MutateKeywordPlanCampaignKeywordResult": "google.ads.googleads.v12.services.types.keyword_plan_campaign_keyword_service", + "MutateKeywordPlanCampaignKeywordsRequest": "google.ads.googleads.v12.services.types.keyword_plan_campaign_keyword_service", + "MutateKeywordPlanCampaignKeywordsResponse": "google.ads.googleads.v12.services.types.keyword_plan_campaign_keyword_service", + "MutateKeywordPlanCampaignResult": "google.ads.googleads.v12.services.types.keyword_plan_campaign_service", + "MutateKeywordPlanCampaignsRequest": "google.ads.googleads.v12.services.types.keyword_plan_campaign_service", + "MutateKeywordPlanCampaignsResponse": "google.ads.googleads.v12.services.types.keyword_plan_campaign_service", + "MutateKeywordPlansRequest": "google.ads.googleads.v12.services.types.keyword_plan_service", + "MutateKeywordPlansResponse": "google.ads.googleads.v12.services.types.keyword_plan_service", + "MutateKeywordPlansResult": "google.ads.googleads.v12.services.types.keyword_plan_service", + "MutateLabelResult": "google.ads.googleads.v12.services.types.label_service", + "MutateLabelsRequest": "google.ads.googleads.v12.services.types.label_service", + "MutateLabelsResponse": "google.ads.googleads.v12.services.types.label_service", + "MutateMediaFileResult": "google.ads.googleads.v12.services.types.media_file_service", + "MutateMediaFilesRequest": "google.ads.googleads.v12.services.types.media_file_service", + "MutateMediaFilesResponse": "google.ads.googleads.v12.services.types.media_file_service", + "MutateMerchantCenterLinkRequest": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "MutateMerchantCenterLinkResponse": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "MutateMerchantCenterLinkResult": "google.ads.googleads.v12.services.types.merchant_center_link_service", + "MutateOperation": "google.ads.googleads.v12.services.types.google_ads_service", + "MutateOperationResponse": "google.ads.googleads.v12.services.types.google_ads_service", + "MutateRemarketingActionResult": "google.ads.googleads.v12.services.types.remarketing_action_service", + "MutateRemarketingActionsRequest": "google.ads.googleads.v12.services.types.remarketing_action_service", + "MutateRemarketingActionsResponse": "google.ads.googleads.v12.services.types.remarketing_action_service", + "MutateSharedCriteriaRequest": "google.ads.googleads.v12.services.types.shared_criterion_service", + "MutateSharedCriteriaResponse": "google.ads.googleads.v12.services.types.shared_criterion_service", + "MutateSharedCriterionResult": "google.ads.googleads.v12.services.types.shared_criterion_service", + "MutateSharedSetResult": "google.ads.googleads.v12.services.types.shared_set_service", + "MutateSharedSetsRequest": "google.ads.googleads.v12.services.types.shared_set_service", + "MutateSharedSetsResponse": "google.ads.googleads.v12.services.types.shared_set_service", + "MutateSmartCampaignSettingResult": "google.ads.googleads.v12.services.types.smart_campaign_setting_service", + "MutateSmartCampaignSettingsRequest": "google.ads.googleads.v12.services.types.smart_campaign_setting_service", + "MutateSmartCampaignSettingsResponse": "google.ads.googleads.v12.services.types.smart_campaign_setting_service", + "MutateUserListResult": "google.ads.googleads.v12.services.types.user_list_service", + "MutateUserListsRequest": "google.ads.googleads.v12.services.types.user_list_service", + "MutateUserListsResponse": "google.ads.googleads.v12.services.types.user_list_service", + "OfflineUserDataJobOperation": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "OnTargetAudienceMetrics": "google.ads.googleads.v12.services.types.reach_plan_service", + "PlannableLocation": "google.ads.googleads.v12.services.types.reach_plan_service", + "PlannableTargeting": "google.ads.googleads.v12.services.types.reach_plan_service", + "PlannedProduct": "google.ads.googleads.v12.services.types.reach_plan_service", + "PlannedProductForecast": "google.ads.googleads.v12.services.types.reach_plan_service", + "PlannedProductReachForecast": "google.ads.googleads.v12.services.types.reach_plan_service", + "ProductMetadata": "google.ads.googleads.v12.services.types.reach_plan_service", + "PromoteCampaignDraftRequest": "google.ads.googleads.v12.services.types.campaign_draft_service", + "PromoteExperimentMetadata": "google.ads.googleads.v12.services.types.experiment_service", + "PromoteExperimentRequest": "google.ads.googleads.v12.services.types.experiment_service", + "ReachCurve": "google.ads.googleads.v12.services.types.reach_plan_service", + "ReachForecast": "google.ads.googleads.v12.services.types.reach_plan_service", + "RegenerateShareableLinkIdRequest": "google.ads.googleads.v12.services.types.third_party_app_analytics_link_service", + "RegenerateShareableLinkIdResponse": "google.ads.googleads.v12.services.types.third_party_app_analytics_link_service", + "RemarketingActionOperation": "google.ads.googleads.v12.services.types.remarketing_action_service", + "RestatementValue": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "RunBatchJobRequest": "google.ads.googleads.v12.services.types.batch_job_service", + "RunOfflineUserDataJobRequest": "google.ads.googleads.v12.services.types.offline_user_data_job_service", + "ScheduleExperimentMetadata": "google.ads.googleads.v12.services.types.experiment_service", + "ScheduleExperimentRequest": "google.ads.googleads.v12.services.types.experiment_service", + "SearchGoogleAdsFieldsRequest": "google.ads.googleads.v12.services.types.google_ads_field_service", + "SearchGoogleAdsFieldsResponse": "google.ads.googleads.v12.services.types.google_ads_field_service", + "SearchGoogleAdsRequest": "google.ads.googleads.v12.services.types.google_ads_service", + "SearchGoogleAdsResponse": "google.ads.googleads.v12.services.types.google_ads_service", + "SearchGoogleAdsStreamRequest": "google.ads.googleads.v12.services.types.google_ads_service", + "SearchGoogleAdsStreamResponse": "google.ads.googleads.v12.services.types.google_ads_service", + "SharedCriterionOperation": "google.ads.googleads.v12.services.types.shared_criterion_service", + "SharedSetOperation": "google.ads.googleads.v12.services.types.shared_set_service", + "SiteSeed": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "SmartCampaignSettingOperation": "google.ads.googleads.v12.services.types.smart_campaign_setting_service", + "SmartCampaignSuggestionInfo": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestGeoTargetConstantsRequest": "google.ads.googleads.v12.services.types.geo_target_constant_service", + "SuggestGeoTargetConstantsResponse": "google.ads.googleads.v12.services.types.geo_target_constant_service", + "SuggestKeywordThemeConstantsRequest": "google.ads.googleads.v12.services.types.keyword_theme_constant_service", + "SuggestKeywordThemeConstantsResponse": "google.ads.googleads.v12.services.types.keyword_theme_constant_service", + "SuggestKeywordThemesRequest": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestKeywordThemesResponse": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestSmartCampaignAdRequest": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestSmartCampaignAdResponse": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestSmartCampaignBudgetOptionsRequest": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "SuggestSmartCampaignBudgetOptionsResponse": "google.ads.googleads.v12.services.types.smart_campaign_suggest_service", + "Targeting": "google.ads.googleads.v12.services.types.reach_plan_service", + "UnusableAdGroup": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "UploadCallConversionsRequest": "google.ads.googleads.v12.services.types.conversion_upload_service", + "UploadCallConversionsResponse": "google.ads.googleads.v12.services.types.conversion_upload_service", + "UploadClickConversionsRequest": "google.ads.googleads.v12.services.types.conversion_upload_service", + "UploadClickConversionsResponse": "google.ads.googleads.v12.services.types.conversion_upload_service", + "UploadConversionAdjustmentsRequest": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "UploadConversionAdjustmentsResponse": "google.ads.googleads.v12.services.types.conversion_adjustment_upload_service", + "UploadUserDataRequest": "google.ads.googleads.v12.services.types.user_data_service", + "UploadUserDataResponse": "google.ads.googleads.v12.services.types.user_data_service", + "UrlSeed": "google.ads.googleads.v12.services.types.keyword_plan_idea_service", + "UserDataOperation": "google.ads.googleads.v12.services.types.user_data_service", + "UserListOperation": "google.ads.googleads.v12.services.types.user_list_service", + "YouTubeChannelAttributeMetadata": "google.ads.googleads.v12.services.types.audience_insights_service", + "YouTubeSelectLineUp": "google.ads.googleads.v12.services.types.reach_plan_service", + "YouTubeSelectSettings": "google.ads.googleads.v12.services.types.reach_plan_service", + # Enum types + # Client classes and transports + "AccountBudgetProposalServiceClient": "google.ads.googleads.v12.services.services.account_budget_proposal_service", + "AccountBudgetProposalServiceTransport": "google.ads.googleads.v12.services.services.account_budget_proposal_service.transports", + "AccountBudgetProposalServiceGrpcTransport": "google.ads.googleads.v12.services.services.account_budget_proposal_service.transports", + "AccountLinkServiceClient": "google.ads.googleads.v12.services.services.account_link_service", + "AccountLinkServiceTransport": "google.ads.googleads.v12.services.services.account_link_service.transports", + "AccountLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.account_link_service.transports", + "AdGroupAdLabelServiceClient": "google.ads.googleads.v12.services.services.ad_group_ad_label_service", + "AdGroupAdLabelServiceTransport": "google.ads.googleads.v12.services.services.ad_group_ad_label_service.transports", + "AdGroupAdLabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_ad_label_service.transports", + "AdGroupAdServiceClient": "google.ads.googleads.v12.services.services.ad_group_ad_service", + "AdGroupAdServiceTransport": "google.ads.googleads.v12.services.services.ad_group_ad_service.transports", + "AdGroupAdServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_ad_service.transports", + "AdGroupAssetServiceClient": "google.ads.googleads.v12.services.services.ad_group_asset_service", + "AdGroupAssetServiceTransport": "google.ads.googleads.v12.services.services.ad_group_asset_service.transports", + "AdGroupAssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_asset_service.transports", + "AdGroupAssetSetServiceClient": "google.ads.googleads.v12.services.services.ad_group_asset_set_service", + "AdGroupAssetSetServiceTransport": "google.ads.googleads.v12.services.services.ad_group_asset_set_service.transports", + "AdGroupAssetSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_asset_set_service.transports", + "AdGroupBidModifierServiceClient": "google.ads.googleads.v12.services.services.ad_group_bid_modifier_service", + "AdGroupBidModifierServiceTransport": "google.ads.googleads.v12.services.services.ad_group_bid_modifier_service.transports", + "AdGroupBidModifierServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_bid_modifier_service.transports", + "AdGroupCriterionCustomizerServiceClient": "google.ads.googleads.v12.services.services.ad_group_criterion_customizer_service", + "AdGroupCriterionCustomizerServiceTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_customizer_service.transports", + "AdGroupCriterionCustomizerServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_customizer_service.transports", + "AdGroupCriterionLabelServiceClient": "google.ads.googleads.v12.services.services.ad_group_criterion_label_service", + "AdGroupCriterionLabelServiceTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_label_service.transports", + "AdGroupCriterionLabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_label_service.transports", + "AdGroupCriterionServiceClient": "google.ads.googleads.v12.services.services.ad_group_criterion_service", + "AdGroupCriterionServiceTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_service.transports", + "AdGroupCriterionServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_criterion_service.transports", + "AdGroupCustomizerServiceClient": "google.ads.googleads.v12.services.services.ad_group_customizer_service", + "AdGroupCustomizerServiceTransport": "google.ads.googleads.v12.services.services.ad_group_customizer_service.transports", + "AdGroupCustomizerServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_customizer_service.transports", + "AdGroupExtensionSettingServiceClient": "google.ads.googleads.v12.services.services.ad_group_extension_setting_service", + "AdGroupExtensionSettingServiceTransport": "google.ads.googleads.v12.services.services.ad_group_extension_setting_service.transports", + "AdGroupExtensionSettingServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_extension_setting_service.transports", + "AdGroupFeedServiceClient": "google.ads.googleads.v12.services.services.ad_group_feed_service", + "AdGroupFeedServiceTransport": "google.ads.googleads.v12.services.services.ad_group_feed_service.transports", + "AdGroupFeedServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_feed_service.transports", + "AdGroupLabelServiceClient": "google.ads.googleads.v12.services.services.ad_group_label_service", + "AdGroupLabelServiceTransport": "google.ads.googleads.v12.services.services.ad_group_label_service.transports", + "AdGroupLabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_label_service.transports", + "AdGroupServiceClient": "google.ads.googleads.v12.services.services.ad_group_service", + "AdGroupServiceTransport": "google.ads.googleads.v12.services.services.ad_group_service.transports", + "AdGroupServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_group_service.transports", + "AdParameterServiceClient": "google.ads.googleads.v12.services.services.ad_parameter_service", + "AdParameterServiceTransport": "google.ads.googleads.v12.services.services.ad_parameter_service.transports", + "AdParameterServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_parameter_service.transports", + "AdServiceClient": "google.ads.googleads.v12.services.services.ad_service", + "AdServiceTransport": "google.ads.googleads.v12.services.services.ad_service.transports", + "AdServiceGrpcTransport": "google.ads.googleads.v12.services.services.ad_service.transports", + "AssetGroupAssetServiceClient": "google.ads.googleads.v12.services.services.asset_group_asset_service", + "AssetGroupAssetServiceTransport": "google.ads.googleads.v12.services.services.asset_group_asset_service.transports", + "AssetGroupAssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_group_asset_service.transports", + "AssetGroupListingGroupFilterServiceClient": "google.ads.googleads.v12.services.services.asset_group_listing_group_filter_service", + "AssetGroupListingGroupFilterServiceTransport": "google.ads.googleads.v12.services.services.asset_group_listing_group_filter_service.transports", + "AssetGroupListingGroupFilterServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_group_listing_group_filter_service.transports", + "AssetGroupServiceClient": "google.ads.googleads.v12.services.services.asset_group_service", + "AssetGroupServiceTransport": "google.ads.googleads.v12.services.services.asset_group_service.transports", + "AssetGroupServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_group_service.transports", + "AssetGroupSignalServiceClient": "google.ads.googleads.v12.services.services.asset_group_signal_service", + "AssetGroupSignalServiceTransport": "google.ads.googleads.v12.services.services.asset_group_signal_service.transports", + "AssetGroupSignalServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_group_signal_service.transports", + "AssetServiceClient": "google.ads.googleads.v12.services.services.asset_service", + "AssetServiceTransport": "google.ads.googleads.v12.services.services.asset_service.transports", + "AssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_service.transports", + "AssetSetAssetServiceClient": "google.ads.googleads.v12.services.services.asset_set_asset_service", + "AssetSetAssetServiceTransport": "google.ads.googleads.v12.services.services.asset_set_asset_service.transports", + "AssetSetAssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_set_asset_service.transports", + "AssetSetServiceClient": "google.ads.googleads.v12.services.services.asset_set_service", + "AssetSetServiceTransport": "google.ads.googleads.v12.services.services.asset_set_service.transports", + "AssetSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.asset_set_service.transports", + "AudienceInsightsServiceClient": "google.ads.googleads.v12.services.services.audience_insights_service", + "AudienceInsightsServiceTransport": "google.ads.googleads.v12.services.services.audience_insights_service.transports", + "AudienceInsightsServiceGrpcTransport": "google.ads.googleads.v12.services.services.audience_insights_service.transports", + "AudienceServiceClient": "google.ads.googleads.v12.services.services.audience_service", + "AudienceServiceTransport": "google.ads.googleads.v12.services.services.audience_service.transports", + "AudienceServiceGrpcTransport": "google.ads.googleads.v12.services.services.audience_service.transports", + "BatchJobServiceClient": "google.ads.googleads.v12.services.services.batch_job_service", + "BatchJobServiceTransport": "google.ads.googleads.v12.services.services.batch_job_service.transports", + "BatchJobServiceGrpcTransport": "google.ads.googleads.v12.services.services.batch_job_service.transports", + "BiddingDataExclusionServiceClient": "google.ads.googleads.v12.services.services.bidding_data_exclusion_service", + "BiddingDataExclusionServiceTransport": "google.ads.googleads.v12.services.services.bidding_data_exclusion_service.transports", + "BiddingDataExclusionServiceGrpcTransport": "google.ads.googleads.v12.services.services.bidding_data_exclusion_service.transports", + "BiddingSeasonalityAdjustmentServiceClient": "google.ads.googleads.v12.services.services.bidding_seasonality_adjustment_service", + "BiddingSeasonalityAdjustmentServiceTransport": "google.ads.googleads.v12.services.services.bidding_seasonality_adjustment_service.transports", + "BiddingSeasonalityAdjustmentServiceGrpcTransport": "google.ads.googleads.v12.services.services.bidding_seasonality_adjustment_service.transports", + "BiddingStrategyServiceClient": "google.ads.googleads.v12.services.services.bidding_strategy_service", + "BiddingStrategyServiceTransport": "google.ads.googleads.v12.services.services.bidding_strategy_service.transports", + "BiddingStrategyServiceGrpcTransport": "google.ads.googleads.v12.services.services.bidding_strategy_service.transports", + "BillingSetupServiceClient": "google.ads.googleads.v12.services.services.billing_setup_service", + "BillingSetupServiceTransport": "google.ads.googleads.v12.services.services.billing_setup_service.transports", + "BillingSetupServiceGrpcTransport": "google.ads.googleads.v12.services.services.billing_setup_service.transports", + "CampaignAssetServiceClient": "google.ads.googleads.v12.services.services.campaign_asset_service", + "CampaignAssetServiceTransport": "google.ads.googleads.v12.services.services.campaign_asset_service.transports", + "CampaignAssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_asset_service.transports", + "CampaignAssetSetServiceClient": "google.ads.googleads.v12.services.services.campaign_asset_set_service", + "CampaignAssetSetServiceTransport": "google.ads.googleads.v12.services.services.campaign_asset_set_service.transports", + "CampaignAssetSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_asset_set_service.transports", + "CampaignBidModifierServiceClient": "google.ads.googleads.v12.services.services.campaign_bid_modifier_service", + "CampaignBidModifierServiceTransport": "google.ads.googleads.v12.services.services.campaign_bid_modifier_service.transports", + "CampaignBidModifierServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_bid_modifier_service.transports", + "CampaignBudgetServiceClient": "google.ads.googleads.v12.services.services.campaign_budget_service", + "CampaignBudgetServiceTransport": "google.ads.googleads.v12.services.services.campaign_budget_service.transports", + "CampaignBudgetServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_budget_service.transports", + "CampaignConversionGoalServiceClient": "google.ads.googleads.v12.services.services.campaign_conversion_goal_service", + "CampaignConversionGoalServiceTransport": "google.ads.googleads.v12.services.services.campaign_conversion_goal_service.transports", + "CampaignConversionGoalServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_conversion_goal_service.transports", + "CampaignCriterionServiceClient": "google.ads.googleads.v12.services.services.campaign_criterion_service", + "CampaignCriterionServiceTransport": "google.ads.googleads.v12.services.services.campaign_criterion_service.transports", + "CampaignCriterionServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_criterion_service.transports", + "CampaignCustomizerServiceClient": "google.ads.googleads.v12.services.services.campaign_customizer_service", + "CampaignCustomizerServiceTransport": "google.ads.googleads.v12.services.services.campaign_customizer_service.transports", + "CampaignCustomizerServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_customizer_service.transports", + "CampaignDraftServiceClient": "google.ads.googleads.v12.services.services.campaign_draft_service", + "CampaignDraftServiceTransport": "google.ads.googleads.v12.services.services.campaign_draft_service.transports", + "CampaignDraftServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_draft_service.transports", + "CampaignExtensionSettingServiceClient": "google.ads.googleads.v12.services.services.campaign_extension_setting_service", + "CampaignExtensionSettingServiceTransport": "google.ads.googleads.v12.services.services.campaign_extension_setting_service.transports", + "CampaignExtensionSettingServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_extension_setting_service.transports", + "CampaignFeedServiceClient": "google.ads.googleads.v12.services.services.campaign_feed_service", + "CampaignFeedServiceTransport": "google.ads.googleads.v12.services.services.campaign_feed_service.transports", + "CampaignFeedServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_feed_service.transports", + "CampaignGroupServiceClient": "google.ads.googleads.v12.services.services.campaign_group_service", + "CampaignGroupServiceTransport": "google.ads.googleads.v12.services.services.campaign_group_service.transports", + "CampaignGroupServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_group_service.transports", + "CampaignLabelServiceClient": "google.ads.googleads.v12.services.services.campaign_label_service", + "CampaignLabelServiceTransport": "google.ads.googleads.v12.services.services.campaign_label_service.transports", + "CampaignLabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_label_service.transports", + "CampaignServiceClient": "google.ads.googleads.v12.services.services.campaign_service", + "CampaignServiceTransport": "google.ads.googleads.v12.services.services.campaign_service.transports", + "CampaignServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_service.transports", + "CampaignSharedSetServiceClient": "google.ads.googleads.v12.services.services.campaign_shared_set_service", + "CampaignSharedSetServiceTransport": "google.ads.googleads.v12.services.services.campaign_shared_set_service.transports", + "CampaignSharedSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.campaign_shared_set_service.transports", + "ConversionActionServiceClient": "google.ads.googleads.v12.services.services.conversion_action_service", + "ConversionActionServiceTransport": "google.ads.googleads.v12.services.services.conversion_action_service.transports", + "ConversionActionServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_action_service.transports", + "ConversionAdjustmentUploadServiceClient": "google.ads.googleads.v12.services.services.conversion_adjustment_upload_service", + "ConversionAdjustmentUploadServiceTransport": "google.ads.googleads.v12.services.services.conversion_adjustment_upload_service.transports", + "ConversionAdjustmentUploadServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_adjustment_upload_service.transports", + "ConversionCustomVariableServiceClient": "google.ads.googleads.v12.services.services.conversion_custom_variable_service", + "ConversionCustomVariableServiceTransport": "google.ads.googleads.v12.services.services.conversion_custom_variable_service.transports", + "ConversionCustomVariableServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_custom_variable_service.transports", + "ConversionGoalCampaignConfigServiceClient": "google.ads.googleads.v12.services.services.conversion_goal_campaign_config_service", + "ConversionGoalCampaignConfigServiceTransport": "google.ads.googleads.v12.services.services.conversion_goal_campaign_config_service.transports", + "ConversionGoalCampaignConfigServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_goal_campaign_config_service.transports", + "ConversionUploadServiceClient": "google.ads.googleads.v12.services.services.conversion_upload_service", + "ConversionUploadServiceTransport": "google.ads.googleads.v12.services.services.conversion_upload_service.transports", + "ConversionUploadServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_upload_service.transports", + "ConversionValueRuleServiceClient": "google.ads.googleads.v12.services.services.conversion_value_rule_service", + "ConversionValueRuleServiceTransport": "google.ads.googleads.v12.services.services.conversion_value_rule_service.transports", + "ConversionValueRuleServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_value_rule_service.transports", + "ConversionValueRuleSetServiceClient": "google.ads.googleads.v12.services.services.conversion_value_rule_set_service", + "ConversionValueRuleSetServiceTransport": "google.ads.googleads.v12.services.services.conversion_value_rule_set_service.transports", + "ConversionValueRuleSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.conversion_value_rule_set_service.transports", + "CustomAudienceServiceClient": "google.ads.googleads.v12.services.services.custom_audience_service", + "CustomAudienceServiceTransport": "google.ads.googleads.v12.services.services.custom_audience_service.transports", + "CustomAudienceServiceGrpcTransport": "google.ads.googleads.v12.services.services.custom_audience_service.transports", + "CustomConversionGoalServiceClient": "google.ads.googleads.v12.services.services.custom_conversion_goal_service", + "CustomConversionGoalServiceTransport": "google.ads.googleads.v12.services.services.custom_conversion_goal_service.transports", + "CustomConversionGoalServiceGrpcTransport": "google.ads.googleads.v12.services.services.custom_conversion_goal_service.transports", + "CustomerAssetServiceClient": "google.ads.googleads.v12.services.services.customer_asset_service", + "CustomerAssetServiceTransport": "google.ads.googleads.v12.services.services.customer_asset_service.transports", + "CustomerAssetServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_asset_service.transports", + "CustomerAssetSetServiceClient": "google.ads.googleads.v12.services.services.customer_asset_set_service", + "CustomerAssetSetServiceTransport": "google.ads.googleads.v12.services.services.customer_asset_set_service.transports", + "CustomerAssetSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_asset_set_service.transports", + "CustomerClientLinkServiceClient": "google.ads.googleads.v12.services.services.customer_client_link_service", + "CustomerClientLinkServiceTransport": "google.ads.googleads.v12.services.services.customer_client_link_service.transports", + "CustomerClientLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_client_link_service.transports", + "CustomerConversionGoalServiceClient": "google.ads.googleads.v12.services.services.customer_conversion_goal_service", + "CustomerConversionGoalServiceTransport": "google.ads.googleads.v12.services.services.customer_conversion_goal_service.transports", + "CustomerConversionGoalServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_conversion_goal_service.transports", + "CustomerCustomizerServiceClient": "google.ads.googleads.v12.services.services.customer_customizer_service", + "CustomerCustomizerServiceTransport": "google.ads.googleads.v12.services.services.customer_customizer_service.transports", + "CustomerCustomizerServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_customizer_service.transports", + "CustomerExtensionSettingServiceClient": "google.ads.googleads.v12.services.services.customer_extension_setting_service", + "CustomerExtensionSettingServiceTransport": "google.ads.googleads.v12.services.services.customer_extension_setting_service.transports", + "CustomerExtensionSettingServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_extension_setting_service.transports", + "CustomerFeedServiceClient": "google.ads.googleads.v12.services.services.customer_feed_service", + "CustomerFeedServiceTransport": "google.ads.googleads.v12.services.services.customer_feed_service.transports", + "CustomerFeedServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_feed_service.transports", + "CustomerLabelServiceClient": "google.ads.googleads.v12.services.services.customer_label_service", + "CustomerLabelServiceTransport": "google.ads.googleads.v12.services.services.customer_label_service.transports", + "CustomerLabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_label_service.transports", + "CustomerManagerLinkServiceClient": "google.ads.googleads.v12.services.services.customer_manager_link_service", + "CustomerManagerLinkServiceTransport": "google.ads.googleads.v12.services.services.customer_manager_link_service.transports", + "CustomerManagerLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_manager_link_service.transports", + "CustomerNegativeCriterionServiceClient": "google.ads.googleads.v12.services.services.customer_negative_criterion_service", + "CustomerNegativeCriterionServiceTransport": "google.ads.googleads.v12.services.services.customer_negative_criterion_service.transports", + "CustomerNegativeCriterionServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_negative_criterion_service.transports", + "CustomerServiceClient": "google.ads.googleads.v12.services.services.customer_service", + "CustomerServiceTransport": "google.ads.googleads.v12.services.services.customer_service.transports", + "CustomerServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_service.transports", + "CustomerUserAccessInvitationServiceClient": "google.ads.googleads.v12.services.services.customer_user_access_invitation_service", + "CustomerUserAccessInvitationServiceTransport": "google.ads.googleads.v12.services.services.customer_user_access_invitation_service.transports", + "CustomerUserAccessInvitationServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_user_access_invitation_service.transports", + "CustomerUserAccessServiceClient": "google.ads.googleads.v12.services.services.customer_user_access_service", + "CustomerUserAccessServiceTransport": "google.ads.googleads.v12.services.services.customer_user_access_service.transports", + "CustomerUserAccessServiceGrpcTransport": "google.ads.googleads.v12.services.services.customer_user_access_service.transports", + "CustomInterestServiceClient": "google.ads.googleads.v12.services.services.custom_interest_service", + "CustomInterestServiceTransport": "google.ads.googleads.v12.services.services.custom_interest_service.transports", + "CustomInterestServiceGrpcTransport": "google.ads.googleads.v12.services.services.custom_interest_service.transports", + "CustomizerAttributeServiceClient": "google.ads.googleads.v12.services.services.customizer_attribute_service", + "CustomizerAttributeServiceTransport": "google.ads.googleads.v12.services.services.customizer_attribute_service.transports", + "CustomizerAttributeServiceGrpcTransport": "google.ads.googleads.v12.services.services.customizer_attribute_service.transports", + "ExperimentArmServiceClient": "google.ads.googleads.v12.services.services.experiment_arm_service", + "ExperimentArmServiceTransport": "google.ads.googleads.v12.services.services.experiment_arm_service.transports", + "ExperimentArmServiceGrpcTransport": "google.ads.googleads.v12.services.services.experiment_arm_service.transports", + "ExperimentServiceClient": "google.ads.googleads.v12.services.services.experiment_service", + "ExperimentServiceTransport": "google.ads.googleads.v12.services.services.experiment_service.transports", + "ExperimentServiceGrpcTransport": "google.ads.googleads.v12.services.services.experiment_service.transports", + "ExtensionFeedItemServiceClient": "google.ads.googleads.v12.services.services.extension_feed_item_service", + "ExtensionFeedItemServiceTransport": "google.ads.googleads.v12.services.services.extension_feed_item_service.transports", + "ExtensionFeedItemServiceGrpcTransport": "google.ads.googleads.v12.services.services.extension_feed_item_service.transports", + "FeedItemServiceClient": "google.ads.googleads.v12.services.services.feed_item_service", + "FeedItemServiceTransport": "google.ads.googleads.v12.services.services.feed_item_service.transports", + "FeedItemServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_item_service.transports", + "FeedItemSetLinkServiceClient": "google.ads.googleads.v12.services.services.feed_item_set_link_service", + "FeedItemSetLinkServiceTransport": "google.ads.googleads.v12.services.services.feed_item_set_link_service.transports", + "FeedItemSetLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_item_set_link_service.transports", + "FeedItemSetServiceClient": "google.ads.googleads.v12.services.services.feed_item_set_service", + "FeedItemSetServiceTransport": "google.ads.googleads.v12.services.services.feed_item_set_service.transports", + "FeedItemSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_item_set_service.transports", + "FeedItemTargetServiceClient": "google.ads.googleads.v12.services.services.feed_item_target_service", + "FeedItemTargetServiceTransport": "google.ads.googleads.v12.services.services.feed_item_target_service.transports", + "FeedItemTargetServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_item_target_service.transports", + "FeedMappingServiceClient": "google.ads.googleads.v12.services.services.feed_mapping_service", + "FeedMappingServiceTransport": "google.ads.googleads.v12.services.services.feed_mapping_service.transports", + "FeedMappingServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_mapping_service.transports", + "FeedServiceClient": "google.ads.googleads.v12.services.services.feed_service", + "FeedServiceTransport": "google.ads.googleads.v12.services.services.feed_service.transports", + "FeedServiceGrpcTransport": "google.ads.googleads.v12.services.services.feed_service.transports", + "GeoTargetConstantServiceClient": "google.ads.googleads.v12.services.services.geo_target_constant_service", + "GeoTargetConstantServiceTransport": "google.ads.googleads.v12.services.services.geo_target_constant_service.transports", + "GeoTargetConstantServiceGrpcTransport": "google.ads.googleads.v12.services.services.geo_target_constant_service.transports", + "GoogleAdsFieldServiceClient": "google.ads.googleads.v12.services.services.google_ads_field_service", + "GoogleAdsFieldServiceTransport": "google.ads.googleads.v12.services.services.google_ads_field_service.transports", + "GoogleAdsFieldServiceGrpcTransport": "google.ads.googleads.v12.services.services.google_ads_field_service.transports", + "GoogleAdsServiceClient": "google.ads.googleads.v12.services.services.google_ads_service", + "GoogleAdsServiceTransport": "google.ads.googleads.v12.services.services.google_ads_service.transports", + "GoogleAdsServiceGrpcTransport": "google.ads.googleads.v12.services.services.google_ads_service.transports", + "InvoiceServiceClient": "google.ads.googleads.v12.services.services.invoice_service", + "InvoiceServiceTransport": "google.ads.googleads.v12.services.services.invoice_service.transports", + "InvoiceServiceGrpcTransport": "google.ads.googleads.v12.services.services.invoice_service.transports", + "KeywordPlanAdGroupKeywordServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_keyword_service", + "KeywordPlanAdGroupKeywordServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_keyword_service.transports", + "KeywordPlanAdGroupKeywordServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_keyword_service.transports", + "KeywordPlanAdGroupServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_service", + "KeywordPlanAdGroupServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_service.transports", + "KeywordPlanAdGroupServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_ad_group_service.transports", + "KeywordPlanCampaignKeywordServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_campaign_keyword_service", + "KeywordPlanCampaignKeywordServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_campaign_keyword_service.transports", + "KeywordPlanCampaignKeywordServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_campaign_keyword_service.transports", + "KeywordPlanCampaignServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_campaign_service", + "KeywordPlanCampaignServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_campaign_service.transports", + "KeywordPlanCampaignServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_campaign_service.transports", + "KeywordPlanIdeaServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_idea_service", + "KeywordPlanIdeaServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_idea_service.transports", + "KeywordPlanIdeaServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_idea_service.transports", + "KeywordPlanServiceClient": "google.ads.googleads.v12.services.services.keyword_plan_service", + "KeywordPlanServiceTransport": "google.ads.googleads.v12.services.services.keyword_plan_service.transports", + "KeywordPlanServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_plan_service.transports", + "KeywordThemeConstantServiceClient": "google.ads.googleads.v12.services.services.keyword_theme_constant_service", + "KeywordThemeConstantServiceTransport": "google.ads.googleads.v12.services.services.keyword_theme_constant_service.transports", + "KeywordThemeConstantServiceGrpcTransport": "google.ads.googleads.v12.services.services.keyword_theme_constant_service.transports", + "LabelServiceClient": "google.ads.googleads.v12.services.services.label_service", + "LabelServiceTransport": "google.ads.googleads.v12.services.services.label_service.transports", + "LabelServiceGrpcTransport": "google.ads.googleads.v12.services.services.label_service.transports", + "MediaFileServiceClient": "google.ads.googleads.v12.services.services.media_file_service", + "MediaFileServiceTransport": "google.ads.googleads.v12.services.services.media_file_service.transports", + "MediaFileServiceGrpcTransport": "google.ads.googleads.v12.services.services.media_file_service.transports", + "MerchantCenterLinkServiceClient": "google.ads.googleads.v12.services.services.merchant_center_link_service", + "MerchantCenterLinkServiceTransport": "google.ads.googleads.v12.services.services.merchant_center_link_service.transports", + "MerchantCenterLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.merchant_center_link_service.transports", + "OfflineUserDataJobServiceClient": "google.ads.googleads.v12.services.services.offline_user_data_job_service", + "OfflineUserDataJobServiceTransport": "google.ads.googleads.v12.services.services.offline_user_data_job_service.transports", + "OfflineUserDataJobServiceGrpcTransport": "google.ads.googleads.v12.services.services.offline_user_data_job_service.transports", + "PaymentsAccountServiceClient": "google.ads.googleads.v12.services.services.payments_account_service", + "PaymentsAccountServiceTransport": "google.ads.googleads.v12.services.services.payments_account_service.transports", + "PaymentsAccountServiceGrpcTransport": "google.ads.googleads.v12.services.services.payments_account_service.transports", + "ReachPlanServiceClient": "google.ads.googleads.v12.services.services.reach_plan_service", + "ReachPlanServiceTransport": "google.ads.googleads.v12.services.services.reach_plan_service.transports", + "ReachPlanServiceGrpcTransport": "google.ads.googleads.v12.services.services.reach_plan_service.transports", + "RecommendationServiceClient": "google.ads.googleads.v12.services.services.recommendation_service", + "RecommendationServiceTransport": "google.ads.googleads.v12.services.services.recommendation_service.transports", + "RecommendationServiceGrpcTransport": "google.ads.googleads.v12.services.services.recommendation_service.transports", + "RemarketingActionServiceClient": "google.ads.googleads.v12.services.services.remarketing_action_service", + "RemarketingActionServiceTransport": "google.ads.googleads.v12.services.services.remarketing_action_service.transports", + "RemarketingActionServiceGrpcTransport": "google.ads.googleads.v12.services.services.remarketing_action_service.transports", + "SharedCriterionServiceClient": "google.ads.googleads.v12.services.services.shared_criterion_service", + "SharedCriterionServiceTransport": "google.ads.googleads.v12.services.services.shared_criterion_service.transports", + "SharedCriterionServiceGrpcTransport": "google.ads.googleads.v12.services.services.shared_criterion_service.transports", + "SharedSetServiceClient": "google.ads.googleads.v12.services.services.shared_set_service", + "SharedSetServiceTransport": "google.ads.googleads.v12.services.services.shared_set_service.transports", + "SharedSetServiceGrpcTransport": "google.ads.googleads.v12.services.services.shared_set_service.transports", + "SmartCampaignSettingServiceClient": "google.ads.googleads.v12.services.services.smart_campaign_setting_service", + "SmartCampaignSettingServiceTransport": "google.ads.googleads.v12.services.services.smart_campaign_setting_service.transports", + "SmartCampaignSettingServiceGrpcTransport": "google.ads.googleads.v12.services.services.smart_campaign_setting_service.transports", + "SmartCampaignSuggestServiceClient": "google.ads.googleads.v12.services.services.smart_campaign_suggest_service", + "SmartCampaignSuggestServiceTransport": "google.ads.googleads.v12.services.services.smart_campaign_suggest_service.transports", + "SmartCampaignSuggestServiceGrpcTransport": "google.ads.googleads.v12.services.services.smart_campaign_suggest_service.transports", + "ThirdPartyAppAnalyticsLinkServiceClient": "google.ads.googleads.v12.services.services.third_party_app_analytics_link_service", + "ThirdPartyAppAnalyticsLinkServiceTransport": "google.ads.googleads.v12.services.services.third_party_app_analytics_link_service.transports", + "ThirdPartyAppAnalyticsLinkServiceGrpcTransport": "google.ads.googleads.v12.services.services.third_party_app_analytics_link_service.transports", + "UserDataServiceClient": "google.ads.googleads.v12.services.services.user_data_service", + "UserDataServiceTransport": "google.ads.googleads.v12.services.services.user_data_service.transports", + "UserDataServiceGrpcTransport": "google.ads.googleads.v12.services.services.user_data_service.transports", + "UserListServiceClient": "google.ads.googleads.v12.services.services.user_list_service", + "UserListServiceTransport": "google.ads.googleads.v12.services.services.user_list_service.transports", + "UserListServiceGrpcTransport": "google.ads.googleads.v12.services.services.user_list_service.transports", +} + + +# Background on how this behaves: https://www.python.org/dev/peps/pep-0562/ +def __getattr__(name): # Requires Python >= 3.7 + if name == "__all__": + all_names = globals()["__all__"] = sorted(_lazy_type_to_package_map) + return all_names + elif name in _lazy_type_to_package_map: + module = importlib.import_module(f"{_lazy_type_to_package_map[name]}") + klass = getattr(module, name) + globals()[name] = klass + return klass + else: + raise AttributeError(f"unknown type {name!r}.") + + +def __dir__(): + return globals().get("__all__") or __getattr__("__all__") diff --git a/google/ads/googleads/v12/common/__init__.py b/google/ads/googleads/v12/common/__init__.py new file mode 100644 index 000000000..f7928dd81 --- /dev/null +++ b/google/ads/googleads/v12/common/__init__.py @@ -0,0 +1,300 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +__all__ = ( + "AdAssetPolicySummary", + "AdDiscoveryCarouselCardAsset", + "AdImageAsset", + "AdMediaBundleAsset", + "AdScheduleInfo", + "AdTextAsset", + "AdVideoAsset", + "AddressInfo", + "AffiliateLocationFeedItem", + "AgeDimension", + "AgeRangeInfo", + "AgeSegment", + "AppAdInfo", + "AppEngagementAdInfo", + "AppFeedItem", + "AppPaymentModelInfo", + "AppPreRegistrationAdInfo", + "AssetInteractionTarget", + "AssetUsage", + "AudienceDimension", + "AudienceExclusionDimension", + "AudienceInfo", + "AudienceSegment", + "AudienceSegmentDimension", + "BasicUserListInfo", + "BidModifierSimulationPoint", + "BidModifierSimulationPointList", + "BookOnGoogleAsset", + "BudgetCampaignAssociationStatus", + "BudgetSimulationPoint", + "BudgetSimulationPointList", + "BusinessNameFilter", + "BusinessProfileBusinessNameFilter", + "BusinessProfileLocation", + "BusinessProfileLocationGroup", + "BusinessProfileLocationSet", + "CallAdInfo", + "CallAsset", + "CallFeedItem", + "CallToActionAsset", + "CalloutAsset", + "CalloutFeedItem", + "CarrierInfo", + "ChainFilter", + "ChainLocationGroup", + "ChainSet", + "ClickLocation", + "CombinedAudienceInfo", + "CombinedRuleUserListInfo", + "Commission", + "ConceptGroup", + "ContentLabelInfo", + "CpcBidSimulationPoint", + "CpcBidSimulationPointList", + "CpvBidSimulationPoint", + "CpvBidSimulationPointList", + "CriterionCategoryAvailability", + "CriterionCategoryChannelAvailability", + "CriterionCategoryLocaleAvailability", + "CrmBasedUserListInfo", + "CustomAffinityInfo", + "CustomAudienceInfo", + "CustomAudienceSegment", + "CustomIntentInfo", + "CustomParameter", + "CustomerMatchUserListMetadata", + "CustomizerValue", + "DateRange", + "DetailedDemographicSegment", + "DeviceInfo", + "DiscoveryCarouselAdInfo", + "DiscoveryCarouselCardAsset", + "DiscoveryMultiAssetAdInfo", + "DisplayUploadAdInfo", + "DynamicAffiliateLocationSetFilter", + "DynamicBusinessProfileLocationGroupFilter", + "DynamicCustomAsset", + "DynamicEducationAsset", + "DynamicFlightsAsset", + "DynamicHotelsAndRentalsAsset", + "DynamicJobsAsset", + "DynamicLocalAsset", + "DynamicLocationSetFilter", + "DynamicRealEstateAsset", + "DynamicTravelAsset", + "EnhancedCpc", + "EventAttribute", + "EventItemAttribute", + "ExclusionSegment", + "ExpandedDynamicSearchAdInfo", + "ExpandedTextAdInfo", + "ExplorerAutoOptimizerSetting", + "ExpressionRuleUserListInfo", + "FinalAppUrl", + "FlexibleRuleOperandInfo", + "FlexibleRuleUserListInfo", + "FrequencyCapEntry", + "FrequencyCapKey", + "GenderDimension", + "GenderInfo", + "GeoPointInfo", + "HistoricalMetricsOptions", + "HotelAdInfo", + "HotelAdvanceBookingWindowInfo", + "HotelCalloutAsset", + "HotelCalloutFeedItem", + "HotelCheckInDateRangeInfo", + "HotelCheckInDayInfo", + "HotelCityInfo", + "HotelClassInfo", + "HotelCountryRegionInfo", + "HotelDateSelectionTypeInfo", + "HotelIdInfo", + "HotelLengthOfStayInfo", + "HotelStateInfo", + "HouseholdIncomeDimension", + "ImageAdInfo", + "ImageAsset", + "ImageDimension", + "ImageFeedItem", + "InFeedVideoAdInfo", + "IncomeRangeInfo", + "InteractionTypeInfo", + "IpBlockInfo", + "ItemAttribute", + "Keyword", + "KeywordAnnotations", + "KeywordConcept", + "KeywordInfo", + "KeywordPlanAggregateMetricResults", + "KeywordPlanAggregateMetrics", + "KeywordPlanDeviceSearches", + "KeywordPlanHistoricalMetrics", + "KeywordThemeInfo", + "LanguageInfo", + "LeadFormAsset", + "LeadFormCustomQuestionField", + "LeadFormDeliveryMethod", + "LeadFormField", + "LeadFormSingleChoiceAnswers", + "LegacyAppInstallAdInfo", + "LegacyResponsiveDisplayAdInfo", + "LifeEventSegment", + "ListingDimensionInfo", + "ListingGroupInfo", + "ListingScopeInfo", + "LocalAdInfo", + "LocationAsset", + "LocationFeedItem", + "LocationGroupInfo", + "LocationInfo", + "LocationSet", + "LogicalUserListInfo", + "LogicalUserListOperandInfo", + "ManualCpa", + "ManualCpc", + "ManualCpm", + "ManualCpv", + "MapsLocationInfo", + "MapsLocationSet", + "MatchingFunction", + "MaximizeConversionValue", + "MaximizeConversions", + "MediaBundleAsset", + "MetricGoal", + "Metrics", + "MobileAppAsset", + "MobileAppCategoryInfo", + "MobileApplicationInfo", + "MobileDeviceInfo", + "Money", + "MonthlySearchVolume", + "OfflineUserAddressInfo", + "Operand", + "OperatingSystemVersionInfo", + "PageFeedAsset", + "ParentalStatusDimension", + "ParentalStatusInfo", + "PercentCpc", + "PercentCpcBidSimulationPoint", + "PercentCpcBidSimulationPointList", + "PlacementInfo", + "PolicySummary", + "PolicyTopicConstraint", + "PolicyTopicEntry", + "PolicyTopicEvidence", + "PolicyValidationParameter", + "PolicyViolationKey", + "PreferredContentInfo", + "PriceAsset", + "PriceFeedItem", + "PriceOffer", + "PriceOffering", + "ProductBiddingCategoryInfo", + "ProductBrandInfo", + "ProductChannelExclusivityInfo", + "ProductChannelInfo", + "ProductConditionInfo", + "ProductCustomAttributeInfo", + "ProductGroupingInfo", + "ProductItemIdInfo", + "ProductLabelsInfo", + "ProductLegacyConditionInfo", + "ProductTypeFullInfo", + "ProductTypeInfo", + "PromotionAsset", + "PromotionFeedItem", + "ProximityInfo", + "RealTimeBiddingSetting", + "ResponsiveDisplayAdControlSpec", + "ResponsiveDisplayAdInfo", + "ResponsiveSearchAdInfo", + "RuleBasedUserListInfo", + "Segments", + "ShoppingComparisonListingAdInfo", + "ShoppingLoyalty", + "ShoppingProductAdInfo", + "ShoppingSmartAdInfo", + "SimilarUserListInfo", + "SitelinkAsset", + "SitelinkFeedItem", + "SkAdNetworkSourceApp", + "SmartCampaignAdInfo", + "StoreAttribute", + "StoreSalesMetadata", + "StoreSalesThirdPartyMetadata", + "StructuredSnippetAsset", + "StructuredSnippetFeedItem", + "TagSnippet", + "TargetCpa", + "TargetCpaSimulationPoint", + "TargetCpaSimulationPointList", + "TargetCpm", + "TargetImpressionShare", + "TargetImpressionShareSimulationPoint", + "TargetImpressionShareSimulationPointList", + "TargetRestriction", + "TargetRestrictionOperation", + "TargetRoas", + "TargetRoasSimulationPoint", + "TargetRoasSimulationPointList", + "TargetSpend", + "TargetingSetting", + "TextAdInfo", + "TextAsset", + "TextLabel", + "TextMessageFeedItem", + "TopicInfo", + "TransactionAttribute", + "UnknownListingDimensionInfo", + "UrlCollection", + "UserAttribute", + "UserData", + "UserIdentifier", + "UserInterestInfo", + "UserInterestSegment", + "UserListActionInfo", + "UserListDateRuleItemInfo", + "UserListInfo", + "UserListLogicalRuleInfo", + "UserListNumberRuleItemInfo", + "UserListRuleInfo", + "UserListRuleItemGroupInfo", + "UserListRuleItemInfo", + "UserListSegment", + "UserListStringRuleItemInfo", + "Value", + "VideoAdInfo", + "VideoBumperInStreamAdInfo", + "VideoNonSkippableInStreamAdInfo", + "VideoOutstreamAdInfo", + "VideoResponsiveAdInfo", + "VideoTrueViewInStreamAdInfo", + "WebhookDelivery", + "WebpageConditionInfo", + "WebpageInfo", + "WebpageSampleInfo", + "YearMonth", + "YearMonthRange", + "YouTubeChannelInfo", + "YouTubeVideoInfo", + "YoutubeVideoAsset", +) diff --git a/google/ads/googleads/v12/common/services/__init__.py b/google/ads/googleads/v12/common/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/common/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/common/types/__init__.py b/google/ads/googleads/v12/common/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/common/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/common/types/ad_asset.py b/google/ads/googleads/v12/common/types/ad_asset.py new file mode 100644 index 000000000..15c49c7f3 --- /dev/null +++ b/google/ads/googleads/v12/common/types/ad_asset.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import asset_policy +from google.ads.googleads.v12.enums.types import ( + asset_performance_label as gage_asset_performance_label, +) +from google.ads.googleads.v12.enums.types import served_asset_field_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "AdTextAsset", + "AdImageAsset", + "AdVideoAsset", + "AdMediaBundleAsset", + "AdDiscoveryCarouselCardAsset", + }, +) + + +class AdTextAsset(proto.Message): + r"""A text asset used inside an ad. + + Attributes: + text (str): + Asset text. + + This field is a member of `oneof`_ ``_text``. + pinned_field (google.ads.googleads.v12.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + The pinned field of the asset. This restricts + the asset to only serve within this field. + Multiple assets can be pinned to the same field. + An asset that is unpinned or pinned to a + different field will not serve in a field where + some other asset has been pinned. + asset_performance_label (google.ads.googleads.v12.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): + The performance label of this text asset. + policy_summary_info (google.ads.googleads.v12.common.types.AdAssetPolicySummary): + The policy summary of this text asset. + """ + + text = proto.Field(proto.STRING, number=4, optional=True,) + pinned_field = proto.Field( + proto.ENUM, + number=2, + enum=served_asset_field_type.ServedAssetFieldTypeEnum.ServedAssetFieldType, + ) + asset_performance_label = proto.Field( + proto.ENUM, + number=5, + enum=gage_asset_performance_label.AssetPerformanceLabelEnum.AssetPerformanceLabel, + ) + policy_summary_info = proto.Field( + proto.MESSAGE, number=6, message=asset_policy.AdAssetPolicySummary, + ) + + +class AdImageAsset(proto.Message): + r"""An image asset used inside an ad. + + Attributes: + asset (str): + The Asset resource name of this image. + + This field is a member of `oneof`_ ``_asset``. + """ + + asset = proto.Field(proto.STRING, number=2, optional=True,) + + +class AdVideoAsset(proto.Message): + r"""A video asset used inside an ad. + + Attributes: + asset (str): + The Asset resource name of this video. + + This field is a member of `oneof`_ ``_asset``. + """ + + asset = proto.Field(proto.STRING, number=2, optional=True,) + + +class AdMediaBundleAsset(proto.Message): + r"""A media bundle asset used inside an ad. + + Attributes: + asset (str): + The Asset resource name of this media bundle. + + This field is a member of `oneof`_ ``_asset``. + """ + + asset = proto.Field(proto.STRING, number=2, optional=True,) + + +class AdDiscoveryCarouselCardAsset(proto.Message): + r"""A discovery carousel card asset used inside an ad. + + Attributes: + asset (str): + The Asset resource name of this discovery + carousel card. + + This field is a member of `oneof`_ ``_asset``. + """ + + asset = proto.Field(proto.STRING, number=1, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/ad_type_infos.py b/google/ads/googleads/v12/common/types/ad_type_infos.py new file mode 100644 index 000000000..ed4e78ca2 --- /dev/null +++ b/google/ads/googleads/v12/common/types/ad_type_infos.py @@ -0,0 +1,1249 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ad_asset +from google.ads.googleads.v12.enums.types import call_conversion_reporting_state +from google.ads.googleads.v12.enums.types import display_ad_format_setting +from google.ads.googleads.v12.enums.types import ( + display_upload_product_type as gage_display_upload_product_type, +) +from google.ads.googleads.v12.enums.types import legacy_app_install_ad_app_store +from google.ads.googleads.v12.enums.types import mime_type as gage_mime_type +from google.ads.googleads.v12.enums.types import video_thumbnail + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "TextAdInfo", + "ExpandedTextAdInfo", + "ExpandedDynamicSearchAdInfo", + "HotelAdInfo", + "ShoppingSmartAdInfo", + "ShoppingProductAdInfo", + "ShoppingComparisonListingAdInfo", + "ImageAdInfo", + "VideoBumperInStreamAdInfo", + "VideoNonSkippableInStreamAdInfo", + "VideoTrueViewInStreamAdInfo", + "VideoOutstreamAdInfo", + "InFeedVideoAdInfo", + "VideoAdInfo", + "VideoResponsiveAdInfo", + "ResponsiveSearchAdInfo", + "LegacyResponsiveDisplayAdInfo", + "AppAdInfo", + "AppEngagementAdInfo", + "AppPreRegistrationAdInfo", + "LegacyAppInstallAdInfo", + "ResponsiveDisplayAdInfo", + "LocalAdInfo", + "DisplayUploadAdInfo", + "ResponsiveDisplayAdControlSpec", + "SmartCampaignAdInfo", + "CallAdInfo", + "DiscoveryMultiAssetAdInfo", + "DiscoveryCarouselAdInfo", + }, +) + + +class TextAdInfo(proto.Message): + r"""A text ad. + + Attributes: + headline (str): + The headline of the ad. + + This field is a member of `oneof`_ ``_headline``. + description1 (str): + The first line of the ad's description. + + This field is a member of `oneof`_ ``_description1``. + description2 (str): + The second line of the ad's description. + + This field is a member of `oneof`_ ``_description2``. + """ + + headline = proto.Field(proto.STRING, number=4, optional=True,) + description1 = proto.Field(proto.STRING, number=5, optional=True,) + description2 = proto.Field(proto.STRING, number=6, optional=True,) + + +class ExpandedTextAdInfo(proto.Message): + r"""An expanded text ad. + + Attributes: + headline_part1 (str): + The first part of the ad's headline. + + This field is a member of `oneof`_ ``_headline_part1``. + headline_part2 (str): + The second part of the ad's headline. + + This field is a member of `oneof`_ ``_headline_part2``. + headline_part3 (str): + The third part of the ad's headline. + + This field is a member of `oneof`_ ``_headline_part3``. + description (str): + The description of the ad. + + This field is a member of `oneof`_ ``_description``. + description2 (str): + The second description of the ad. + + This field is a member of `oneof`_ ``_description2``. + path1 (str): + The text that can appear alongside the ad's + displayed URL. + + This field is a member of `oneof`_ ``_path1``. + path2 (str): + Additional text that can appear alongside the + ad's displayed URL. + + This field is a member of `oneof`_ ``_path2``. + """ + + headline_part1 = proto.Field(proto.STRING, number=8, optional=True,) + headline_part2 = proto.Field(proto.STRING, number=9, optional=True,) + headline_part3 = proto.Field(proto.STRING, number=10, optional=True,) + description = proto.Field(proto.STRING, number=11, optional=True,) + description2 = proto.Field(proto.STRING, number=12, optional=True,) + path1 = proto.Field(proto.STRING, number=13, optional=True,) + path2 = proto.Field(proto.STRING, number=14, optional=True,) + + +class ExpandedDynamicSearchAdInfo(proto.Message): + r"""An expanded dynamic search ad. + + Attributes: + description (str): + The description of the ad. + + This field is a member of `oneof`_ ``_description``. + description2 (str): + The second description of the ad. + + This field is a member of `oneof`_ ``_description2``. + """ + + description = proto.Field(proto.STRING, number=3, optional=True,) + description2 = proto.Field(proto.STRING, number=4, optional=True,) + + +class HotelAdInfo(proto.Message): + r"""A hotel ad. + """ + + +class ShoppingSmartAdInfo(proto.Message): + r"""A Smart Shopping ad. + """ + + +class ShoppingProductAdInfo(proto.Message): + r"""A standard Shopping ad. + """ + + +class ShoppingComparisonListingAdInfo(proto.Message): + r"""A Shopping Comparison Listing ad. + + Attributes: + headline (str): + Headline of the ad. This field is required. + Allowed length is between 25 and 45 characters. + + This field is a member of `oneof`_ ``_headline``. + """ + + headline = proto.Field(proto.STRING, number=2, optional=True,) + + +class ImageAdInfo(proto.Message): + r"""An image ad. + + 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: + pixel_width (int): + Width in pixels of the full size image. + + This field is a member of `oneof`_ ``_pixel_width``. + pixel_height (int): + Height in pixels of the full size image. + + This field is a member of `oneof`_ ``_pixel_height``. + image_url (str): + URL of the full size image. + + This field is a member of `oneof`_ ``_image_url``. + preview_pixel_width (int): + Width in pixels of the preview size image. + + This field is a member of `oneof`_ ``_preview_pixel_width``. + preview_pixel_height (int): + Height in pixels of the preview size image. + + This field is a member of `oneof`_ ``_preview_pixel_height``. + preview_image_url (str): + URL of the preview size image. + + This field is a member of `oneof`_ ``_preview_image_url``. + mime_type (google.ads.googleads.v12.enums.types.MimeTypeEnum.MimeType): + The mime type of the image. + name (str): + The name of the image. If the image was + created from a MediaFile, this is the + MediaFile's name. If the image was created from + bytes, this is empty. + + This field is a member of `oneof`_ ``_name``. + media_file (str): + The MediaFile resource to use for the image. + + This field is a member of `oneof`_ ``image``. + data (bytes): + Raw image data as bytes. + + This field is a member of `oneof`_ ``image``. + ad_id_to_copy_image_from (int): + An ad ID to copy the image from. + + This field is a member of `oneof`_ ``image``. + """ + + pixel_width = proto.Field(proto.INT64, number=15, optional=True,) + pixel_height = proto.Field(proto.INT64, number=16, optional=True,) + image_url = proto.Field(proto.STRING, number=17, optional=True,) + preview_pixel_width = proto.Field(proto.INT64, number=18, optional=True,) + preview_pixel_height = proto.Field(proto.INT64, number=19, optional=True,) + preview_image_url = proto.Field(proto.STRING, number=20, optional=True,) + mime_type = proto.Field( + proto.ENUM, number=10, enum=gage_mime_type.MimeTypeEnum.MimeType, + ) + name = proto.Field(proto.STRING, number=21, optional=True,) + media_file = proto.Field(proto.STRING, number=12, oneof="image",) + data = proto.Field(proto.BYTES, number=13, oneof="image",) + ad_id_to_copy_image_from = proto.Field( + proto.INT64, number=14, oneof="image", + ) + + +class VideoBumperInStreamAdInfo(proto.Message): + r"""Representation of video bumper in-stream ad format (very + short in-stream non-skippable video ad). + + Attributes: + companion_banner (google.ads.googleads.v12.common.types.AdImageAsset): + The image assets of the companion banner used + with the ad. + """ + + companion_banner = proto.Field( + proto.MESSAGE, number=3, message=ad_asset.AdImageAsset, + ) + + +class VideoNonSkippableInStreamAdInfo(proto.Message): + r"""Representation of video non-skippable in-stream ad format (15 + second in-stream non-skippable video ad). + + Attributes: + companion_banner (google.ads.googleads.v12.common.types.AdImageAsset): + The image assets of the companion banner used + with the ad. + action_button_label (str): + Label on the "Call To Action" button taking + the user to the video ad's final URL. + action_headline (str): + Additional text displayed with the "Call To + Action" button to give context and encourage + clicking on the button. + """ + + companion_banner = proto.Field( + proto.MESSAGE, number=5, message=ad_asset.AdImageAsset, + ) + action_button_label = proto.Field(proto.STRING, number=3,) + action_headline = proto.Field(proto.STRING, number=4,) + + +class VideoTrueViewInStreamAdInfo(proto.Message): + r"""Representation of video TrueView in-stream ad format (ad + shown during video playback, often at beginning, which displays + a skip button a few seconds into the video). + + Attributes: + action_button_label (str): + Label on the CTA (call-to-action) button + taking the user to the video ad's final URL. + Required for TrueView for action campaigns, + optional otherwise. + action_headline (str): + Additional text displayed with the CTA + (call-to-action) button to give context and + encourage clicking on the button. + companion_banner (google.ads.googleads.v12.common.types.AdImageAsset): + The image assets of the companion banner used + with the ad. + """ + + action_button_label = proto.Field(proto.STRING, number=4,) + action_headline = proto.Field(proto.STRING, number=5,) + companion_banner = proto.Field( + proto.MESSAGE, number=7, message=ad_asset.AdImageAsset, + ) + + +class VideoOutstreamAdInfo(proto.Message): + r"""Representation of video out-stream ad format (ad shown + alongside a feed with automatic playback, without sound). + + Attributes: + headline (str): + The headline of the ad. + description (str): + The description line. + """ + + headline = proto.Field(proto.STRING, number=3,) + description = proto.Field(proto.STRING, number=4,) + + +class InFeedVideoAdInfo(proto.Message): + r"""Representation of In-feed video ad format. + + Attributes: + headline (str): + The headline of the ad. + description1 (str): + First text line for the ad. + description2 (str): + Second text line for the ad. + thumbnail (google.ads.googleads.v12.enums.types.VideoThumbnailEnum.VideoThumbnail): + Video thumbnail image to use. + """ + + headline = proto.Field(proto.STRING, number=1,) + description1 = proto.Field(proto.STRING, number=2,) + description2 = proto.Field(proto.STRING, number=3,) + thumbnail = proto.Field( + proto.ENUM, + number=4, + enum=video_thumbnail.VideoThumbnailEnum.VideoThumbnail, + ) + + +class VideoAdInfo(proto.Message): + r"""A video ad. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + video (google.ads.googleads.v12.common.types.AdVideoAsset): + The YouTube video assets used for the ad. + in_stream (google.ads.googleads.v12.common.types.VideoTrueViewInStreamAdInfo): + Video TrueView in-stream ad format. + + This field is a member of `oneof`_ ``format``. + bumper (google.ads.googleads.v12.common.types.VideoBumperInStreamAdInfo): + Video bumper in-stream ad format. + + This field is a member of `oneof`_ ``format``. + out_stream (google.ads.googleads.v12.common.types.VideoOutstreamAdInfo): + Video out-stream ad format. + + This field is a member of `oneof`_ ``format``. + non_skippable (google.ads.googleads.v12.common.types.VideoNonSkippableInStreamAdInfo): + Video non-skippable in-stream ad format. + + This field is a member of `oneof`_ ``format``. + in_feed (google.ads.googleads.v12.common.types.InFeedVideoAdInfo): + In-feed video ad format. + + This field is a member of `oneof`_ ``format``. + """ + + video = proto.Field(proto.MESSAGE, number=8, message=ad_asset.AdVideoAsset,) + in_stream = proto.Field( + proto.MESSAGE, + number=2, + oneof="format", + message="VideoTrueViewInStreamAdInfo", + ) + bumper = proto.Field( + proto.MESSAGE, + number=3, + oneof="format", + message="VideoBumperInStreamAdInfo", + ) + out_stream = proto.Field( + proto.MESSAGE, number=4, oneof="format", message="VideoOutstreamAdInfo", + ) + non_skippable = proto.Field( + proto.MESSAGE, + number=5, + oneof="format", + message="VideoNonSkippableInStreamAdInfo", + ) + in_feed = proto.Field( + proto.MESSAGE, number=9, oneof="format", message="InFeedVideoAdInfo", + ) + + +class VideoResponsiveAdInfo(proto.Message): + r"""A video responsive ad. + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets used for the short + headline, for example, the "Call To Action" + banner. Currently, only a single value for the + short headline is supported. + long_headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets used for the long + headline. Currently, only a single value for the + long headline is supported. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets used for the description. + Currently, only a single value for the + description is supported. + call_to_actions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets used for the button, for + example, the "Call To Action" button. Currently, + only a single value for the button is supported. + videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + List of YouTube video assets used for the ad. + Currently, only a single value for the YouTube + video asset is supported. + companion_banners (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of image assets used for the companion + banner. Currently, only a single value for the + companion banner asset is supported. + breadcrumb1 (str): + First part of text that appears in the ad + with the displayed URL. + breadcrumb2 (str): + Second part of text that appears in the ad + with the displayed URL. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + long_headlines = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdTextAsset, + ) + call_to_actions = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdTextAsset, + ) + videos = proto.RepeatedField( + proto.MESSAGE, number=5, message=ad_asset.AdVideoAsset, + ) + companion_banners = proto.RepeatedField( + proto.MESSAGE, number=6, message=ad_asset.AdImageAsset, + ) + breadcrumb1 = proto.Field(proto.STRING, number=7,) + breadcrumb2 = proto.Field(proto.STRING, number=8,) + + +class ResponsiveSearchAdInfo(proto.Message): + r"""A responsive search ad. + Responsive search ads let you create an ad that adapts to show + more text, and more relevant messages, to your customers. Enter + multiple headlines and descriptions when creating a responsive + search ad, and over time, Google Ads will automatically test + different combinations and learn which combinations perform + best. By adapting your ad's content to more closely match + potential customers' search terms, responsive search ads may + improve your campaign's performance. + + More information at + https://support.google.com/google-ads/answer/7684791 + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for headlines. When the + ad serves the headlines will be selected from + this list. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for descriptions. When + the ad serves the descriptions will be selected + from this list. + path1 (str): + First part of text that can be appended to + the URL in the ad. + + This field is a member of `oneof`_ ``_path1``. + path2 (str): + Second part of text that can be appended to the URL in the + ad. This field can only be set when ``path1`` is also set. + + This field is a member of `oneof`_ ``_path2``. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + path1 = proto.Field(proto.STRING, number=5, optional=True,) + path2 = proto.Field(proto.STRING, number=6, optional=True,) + + +class LegacyResponsiveDisplayAdInfo(proto.Message): + r"""A legacy responsive display ad. Ads of this type are labeled + 'Responsive ads' in the Google Ads UI. + + Attributes: + short_headline (str): + The short version of the ad's headline. + + This field is a member of `oneof`_ ``_short_headline``. + long_headline (str): + The long version of the ad's headline. + + This field is a member of `oneof`_ ``_long_headline``. + description (str): + The description of the ad. + + This field is a member of `oneof`_ ``_description``. + business_name (str): + The business name in the ad. + + This field is a member of `oneof`_ ``_business_name``. + allow_flexible_color (bool): + Advertiser's consent to allow flexible color. When true, the + ad may be served with different color if necessary. When + false, the ad will be served with the specified colors or a + neutral color. The default value is ``true``. Must be true + if ``main_color`` and ``accent_color`` are not set. + + This field is a member of `oneof`_ ``_allow_flexible_color``. + accent_color (str): + The accent color of the ad in hexadecimal, for example, + #ffffff for white. If one of ``main_color`` and + ``accent_color`` is set, the other is required as well. + + This field is a member of `oneof`_ ``_accent_color``. + main_color (str): + The main color of the ad in hexadecimal, for example, + #ffffff for white. If one of ``main_color`` and + ``accent_color`` is set, the other is required as well. + + This field is a member of `oneof`_ ``_main_color``. + call_to_action_text (str): + The call-to-action text for the ad. + + This field is a member of `oneof`_ ``_call_to_action_text``. + logo_image (str): + The MediaFile resource name of the logo image + used in the ad. + + This field is a member of `oneof`_ ``_logo_image``. + square_logo_image (str): + The MediaFile resource name of the square + logo image used in the ad. + + This field is a member of `oneof`_ ``_square_logo_image``. + marketing_image (str): + The MediaFile resource name of the marketing + image used in the ad. + + This field is a member of `oneof`_ ``_marketing_image``. + square_marketing_image (str): + The MediaFile resource name of the square + marketing image used in the ad. + + This field is a member of `oneof`_ ``_square_marketing_image``. + format_setting (google.ads.googleads.v12.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): + Specifies which format the ad will be served in. Default is + ALL_FORMATS. + price_prefix (str): + Prefix before price. For example, 'as low + as'. + + This field is a member of `oneof`_ ``_price_prefix``. + promo_text (str): + Promotion text used for dynamic formats of + responsive ads. For example 'Free two-day + shipping'. + + This field is a member of `oneof`_ ``_promo_text``. + """ + + short_headline = proto.Field(proto.STRING, number=16, optional=True,) + long_headline = proto.Field(proto.STRING, number=17, optional=True,) + description = proto.Field(proto.STRING, number=18, optional=True,) + business_name = proto.Field(proto.STRING, number=19, optional=True,) + allow_flexible_color = proto.Field(proto.BOOL, number=20, optional=True,) + accent_color = proto.Field(proto.STRING, number=21, optional=True,) + main_color = proto.Field(proto.STRING, number=22, optional=True,) + call_to_action_text = proto.Field(proto.STRING, number=23, optional=True,) + logo_image = proto.Field(proto.STRING, number=24, optional=True,) + square_logo_image = proto.Field(proto.STRING, number=25, optional=True,) + marketing_image = proto.Field(proto.STRING, number=26, optional=True,) + square_marketing_image = proto.Field( + proto.STRING, number=27, optional=True, + ) + format_setting = proto.Field( + proto.ENUM, + number=13, + enum=display_ad_format_setting.DisplayAdFormatSettingEnum.DisplayAdFormatSetting, + ) + price_prefix = proto.Field(proto.STRING, number=28, optional=True,) + promo_text = proto.Field(proto.STRING, number=29, optional=True,) + + +class AppAdInfo(proto.Message): + r"""An app ad. + + Attributes: + mandatory_ad_text (google.ads.googleads.v12.common.types.AdTextAsset): + Mandatory ad text. + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for headlines. When the + ad serves the headlines will be selected from + this list. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for descriptions. When + the ad serves the descriptions will be selected + from this list. + images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of image assets that may be displayed + with the ad. + youtube_videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + List of YouTube video assets that may be + displayed with the ad. + html5_media_bundles (Sequence[google.ads.googleads.v12.common.types.AdMediaBundleAsset]): + List of media bundle assets that may be used + with the ad. + """ + + mandatory_ad_text = proto.Field( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + headlines = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdTextAsset, + ) + images = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdImageAsset, + ) + youtube_videos = proto.RepeatedField( + proto.MESSAGE, number=5, message=ad_asset.AdVideoAsset, + ) + html5_media_bundles = proto.RepeatedField( + proto.MESSAGE, number=6, message=ad_asset.AdMediaBundleAsset, + ) + + +class AppEngagementAdInfo(proto.Message): + r"""App engagement ads allow you to write text encouraging a + specific action in the app, like checking in, making a purchase, + or booking a flight. They allow you to send users to a specific + part of your app where they can find what they're looking for + easier and faster. + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for headlines. When the + ad serves the headlines will be selected from + this list. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for descriptions. When + the ad serves the descriptions will be selected + from this list. + images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of image assets that may be displayed + with the ad. + videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + List of video assets that may be displayed + with the ad. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + images = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdImageAsset, + ) + videos = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdVideoAsset, + ) + + +class AppPreRegistrationAdInfo(proto.Message): + r"""App pre-registration ads link to your app or game listing on + Google Play, and can run on Google Play, on YouTube (in-stream + only), and within other apps and mobile websites on the Display + Network. It will help capture people's interest in your app or + game and generate an early install base for your app or game + before a launch. + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for headlines. When the + ad serves the headlines will be selected from + this list. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for descriptions. When + the ad serves the descriptions will be selected + from this list. + images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of image asset IDs whose images may be + displayed with the ad. + youtube_videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + List of YouTube video asset IDs whose videos + may be displayed with the ad. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + images = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdImageAsset, + ) + youtube_videos = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdVideoAsset, + ) + + +class LegacyAppInstallAdInfo(proto.Message): + r"""A legacy app install ad that only can be used by a few select + customers. + + Attributes: + app_id (str): + The ID of the mobile app. + + This field is a member of `oneof`_ ``_app_id``. + app_store (google.ads.googleads.v12.enums.types.LegacyAppInstallAdAppStoreEnum.LegacyAppInstallAdAppStore): + The app store the mobile app is available in. + headline (str): + The headline of the ad. + + This field is a member of `oneof`_ ``_headline``. + description1 (str): + The first description line of the ad. + + This field is a member of `oneof`_ ``_description1``. + description2 (str): + The second description line of the ad. + + This field is a member of `oneof`_ ``_description2``. + """ + + app_id = proto.Field(proto.STRING, number=6, optional=True,) + app_store = proto.Field( + proto.ENUM, + number=2, + enum=legacy_app_install_ad_app_store.LegacyAppInstallAdAppStoreEnum.LegacyAppInstallAdAppStore, + ) + headline = proto.Field(proto.STRING, number=7, optional=True,) + description1 = proto.Field(proto.STRING, number=8, optional=True,) + description2 = proto.Field(proto.STRING, number=9, optional=True,) + + +class ResponsiveDisplayAdInfo(proto.Message): + r"""A responsive display ad. + + Attributes: + marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Marketing images to be used in the ad. Valid image types are + GIF, JPEG, and PNG. The minimum size is 600x314 and the + aspect ratio must be 1.91:1 (+-1%). At least one + ``marketing_image`` is required. Combined with + ``square_marketing_images``, the maximum is 15. + square_marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Square marketing images to be used in the ad. Valid image + types are GIF, JPEG, and PNG. The minimum size is 300x300 + and the aspect ratio must be 1:1 (+-1%). At least one square + ``marketing_image`` is required. Combined with + ``marketing_images``, the maximum is 15. + logo_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Logo images to be used in the ad. Valid image types are GIF, + JPEG, and PNG. The minimum size is 512x128 and the aspect + ratio must be 4:1 (+-1%). Combined with + ``square_logo_images``, the maximum is 5. + square_logo_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Square logo images to be used in the ad. Valid image types + are GIF, JPEG, and PNG. The minimum size is 128x128 and the + aspect ratio must be 1:1 (+-1%). Combined with + ``square_logo_images``, the maximum is 5. + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + Short format headlines for the ad. The + maximum length is 30 characters. At least 1 and + max 5 headlines can be specified. + long_headline (google.ads.googleads.v12.common.types.AdTextAsset): + A required long format headline. The maximum + length is 90 characters. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + Descriptive texts for the ad. The maximum + length is 90 characters. At least 1 and max 5 + headlines can be specified. + youtube_videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + Optional YouTube videos for the ad. A maximum + of 5 videos can be specified. + business_name (str): + The advertiser/brand name. Maximum display + width is 25. + + This field is a member of `oneof`_ ``_business_name``. + main_color (str): + The main color of the ad in hexadecimal, for example, + #ffffff for white. If one of ``main_color`` and + ``accent_color`` is set, the other is required as well. + + This field is a member of `oneof`_ ``_main_color``. + accent_color (str): + The accent color of the ad in hexadecimal, for example, + #ffffff for white. If one of ``main_color`` and + ``accent_color`` is set, the other is required as well. + + This field is a member of `oneof`_ ``_accent_color``. + allow_flexible_color (bool): + Advertiser's consent to allow flexible color. When true, the + ad may be served with different color if necessary. When + false, the ad will be served with the specified colors or a + neutral color. The default value is ``true``. Must be true + if ``main_color`` and ``accent_color`` are not set. + + This field is a member of `oneof`_ ``_allow_flexible_color``. + call_to_action_text (str): + The call-to-action text for the ad. Maximum + display width is 30. + + This field is a member of `oneof`_ ``_call_to_action_text``. + price_prefix (str): + Prefix before price. For example, 'as low + as'. + + This field is a member of `oneof`_ ``_price_prefix``. + promo_text (str): + Promotion text used for dynamic formats of + responsive ads. For example 'Free two-day + shipping'. + + This field is a member of `oneof`_ ``_promo_text``. + format_setting (google.ads.googleads.v12.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): + Specifies which format the ad will be served in. Default is + ALL_FORMATS. + control_spec (google.ads.googleads.v12.common.types.ResponsiveDisplayAdControlSpec): + Specification for various creative controls. + """ + + marketing_images = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdImageAsset, + ) + square_marketing_images = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdImageAsset, + ) + logo_images = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdImageAsset, + ) + square_logo_images = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdImageAsset, + ) + headlines = proto.RepeatedField( + proto.MESSAGE, number=5, message=ad_asset.AdTextAsset, + ) + long_headline = proto.Field( + proto.MESSAGE, number=6, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=7, message=ad_asset.AdTextAsset, + ) + youtube_videos = proto.RepeatedField( + proto.MESSAGE, number=8, message=ad_asset.AdVideoAsset, + ) + business_name = proto.Field(proto.STRING, number=17, optional=True,) + main_color = proto.Field(proto.STRING, number=18, optional=True,) + accent_color = proto.Field(proto.STRING, number=19, optional=True,) + allow_flexible_color = proto.Field(proto.BOOL, number=20, optional=True,) + call_to_action_text = proto.Field(proto.STRING, number=21, optional=True,) + price_prefix = proto.Field(proto.STRING, number=22, optional=True,) + promo_text = proto.Field(proto.STRING, number=23, optional=True,) + format_setting = proto.Field( + proto.ENUM, + number=16, + enum=display_ad_format_setting.DisplayAdFormatSettingEnum.DisplayAdFormatSetting, + ) + control_spec = proto.Field( + proto.MESSAGE, number=24, message="ResponsiveDisplayAdControlSpec", + ) + + +class LocalAdInfo(proto.Message): + r"""A local ad. + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for headlines. When the + ad serves the headlines will be selected from + this list. At least 1 and at most 5 headlines + must be specified. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for descriptions. When + the ad serves the descriptions will be selected + from this list. At least 1 and at most 5 + descriptions must be specified. + call_to_actions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets for call-to-actions. When + the ad serves the call-to-actions will be + selected from this list. At least 1 and at most + 5 call-to-actions must be specified. + marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of marketing image assets that may be + displayed with the ad. The images must be + 314x600 pixels or 320x320 pixels. At least 1 and + at most 20 image assets must be specified. + logo_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + List of logo image assets that may be + displayed with the ad. The images must be + 128x128 pixels and not larger than 120KB. At + least 1 and at most 5 image assets must be + specified. + videos (Sequence[google.ads.googleads.v12.common.types.AdVideoAsset]): + List of YouTube video assets that may be + displayed with the ad. At least 1 and at most 20 + video assets must be specified. + path1 (str): + First part of optional text that can be + appended to the URL in the ad. + + This field is a member of `oneof`_ ``_path1``. + path2 (str): + Second part of optional text that can be appended to the URL + in the ad. This field can only be set when ``path1`` is also + set. + + This field is a member of `oneof`_ ``_path2``. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + call_to_actions = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdTextAsset, + ) + marketing_images = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdImageAsset, + ) + logo_images = proto.RepeatedField( + proto.MESSAGE, number=5, message=ad_asset.AdImageAsset, + ) + videos = proto.RepeatedField( + proto.MESSAGE, number=6, message=ad_asset.AdVideoAsset, + ) + path1 = proto.Field(proto.STRING, number=9, optional=True,) + path2 = proto.Field(proto.STRING, number=10, optional=True,) + + +class DisplayUploadAdInfo(proto.Message): + r"""A generic type of display ad. The exact ad format is controlled by + the ``display_upload_product_type`` field, which determines what + kinds of data need to be included with the ad. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + display_upload_product_type (google.ads.googleads.v12.enums.types.DisplayUploadProductTypeEnum.DisplayUploadProductType): + The product type of this ad. See comments on + the enum for details. + media_bundle (google.ads.googleads.v12.common.types.AdMediaBundleAsset): + A media bundle asset to be used in the ad. For information + about the media bundle for HTML5_UPLOAD_AD, see + https://support.google.com/google-ads/answer/1722096 Media + bundles that are part of dynamic product types use a special + format that needs to be created through the Google Web + Designer. See + https://support.google.com/webdesigner/answer/7543898 for + more information. + + This field is a member of `oneof`_ ``media_asset``. + """ + + display_upload_product_type = proto.Field( + proto.ENUM, + number=1, + enum=gage_display_upload_product_type.DisplayUploadProductTypeEnum.DisplayUploadProductType, + ) + media_bundle = proto.Field( + proto.MESSAGE, + number=2, + oneof="media_asset", + message=ad_asset.AdMediaBundleAsset, + ) + + +class ResponsiveDisplayAdControlSpec(proto.Message): + r"""Specification for various creative controls for a responsive + display ad. + + Attributes: + enable_asset_enhancements (bool): + Whether the advertiser has opted into the + asset enhancements feature. + enable_autogen_video (bool): + Whether the advertiser has opted into + auto-gen video feature. + """ + + enable_asset_enhancements = proto.Field(proto.BOOL, number=1,) + enable_autogen_video = proto.Field(proto.BOOL, number=2,) + + +class SmartCampaignAdInfo(proto.Message): + r"""A Smart campaign ad. + + Attributes: + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets, each of which + corresponds to a headline when the ad serves. + This list consists of a minimum of 3 and up to + 15 text assets. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + List of text assets, each of which + corresponds to a description when the ad serves. + This list consists of a minimum of 2 and up to 4 + text assets. + """ + + headlines = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdTextAsset, + ) + + +class CallAdInfo(proto.Message): + r"""A call ad. + + Attributes: + country_code (str): + The country code in the ad. + phone_number (str): + The phone number in the ad. + business_name (str): + The business name in the ad. + headline1 (str): + First headline in the ad. + headline2 (str): + Second headline in the ad. + description1 (str): + The first line of the ad's description. + description2 (str): + The second line of the ad's description. + call_tracked (bool): + Whether to enable call tracking for the + creative. Enabling call tracking also enables + call conversions. + disable_call_conversion (bool): + Whether to disable call conversion for the creative. If set + to ``true``, disables call conversions even when + ``call_tracked`` is ``true``. If ``call_tracked`` is + ``false``, this field is ignored. + phone_number_verification_url (str): + The URL to be used for phone number + verification. + conversion_action (str): + The conversion action to attribute a call conversion to. If + not set a default conversion action is used. This field only + has effect if ``call_tracked`` is set to ``true``. Otherwise + this field is ignored. + conversion_reporting_state (google.ads.googleads.v12.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): + The call conversion behavior of this call ad. + It can use its own call conversion setting, + inherit the account level setting, or be + disabled. + path1 (str): + First part of text that can be appended to + the URL in the ad. Optional. + path2 (str): + Second part of text that can be appended to the URL in the + ad. This field can only be set when ``path1`` is also set. + Optional. + """ + + country_code = proto.Field(proto.STRING, number=1,) + phone_number = proto.Field(proto.STRING, number=2,) + business_name = proto.Field(proto.STRING, number=3,) + headline1 = proto.Field(proto.STRING, number=11,) + headline2 = proto.Field(proto.STRING, number=12,) + description1 = proto.Field(proto.STRING, number=4,) + description2 = proto.Field(proto.STRING, number=5,) + call_tracked = proto.Field(proto.BOOL, number=6,) + disable_call_conversion = proto.Field(proto.BOOL, number=7,) + phone_number_verification_url = proto.Field(proto.STRING, number=8,) + conversion_action = proto.Field(proto.STRING, number=9,) + conversion_reporting_state = proto.Field( + proto.ENUM, + number=10, + enum=call_conversion_reporting_state.CallConversionReportingStateEnum.CallConversionReportingState, + ) + path1 = proto.Field(proto.STRING, number=13,) + path2 = proto.Field(proto.STRING, number=14,) + + +class DiscoveryMultiAssetAdInfo(proto.Message): + r"""A discovery multi asset ad. + + Attributes: + marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Marketing image assets to be used in the ad. Valid image + types are GIF, JPEG, and PNG. The minimum size is 600x314 + and the aspect ratio must be 1.91:1 (+-1%). Required if + square_marketing_images is not present. Combined with + ``square_marketing_images`` and + ``portrait_marketing_images`` the maximum is 20. + square_marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Square marketing image assets to be used in the ad. Valid + image types are GIF, JPEG, and PNG. The minimum size is + 300x300 and the aspect ratio must be 1:1 (+-1%). Required if + marketing_images is not present. Combined with + ``marketing_images`` and ``portrait_marketing_images`` the + maximum is 20. + portrait_marketing_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Portrait marketing image assets to be used in the ad. Valid + image types are GIF, JPEG, and PNG. The minimum size is + 480x600 and the aspect ratio must be 4:5 (+-1%). Combined + with ``marketing_images`` and ``square_marketing_images`` + the maximum is 20. + logo_images (Sequence[google.ads.googleads.v12.common.types.AdImageAsset]): + Logo image assets to be used in the ad. Valid + image types are GIF, JPEG, and PNG. The minimum + size is 128x128 and the aspect ratio must be + 1:1(+-1%). At least 1 and max 5 logo images can + be specified. + headlines (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + Headline text asset of the ad. Maximum + display width is 30. At least 1 and max 5 + headlines can be specified. + descriptions (Sequence[google.ads.googleads.v12.common.types.AdTextAsset]): + The descriptive text of the ad. Maximum + display width is 90. At least 1 and max 5 + descriptions can be specified. + business_name (str): + The Advertiser/brand name. Maximum display + width is 25. Required. + + This field is a member of `oneof`_ ``_business_name``. + call_to_action_text (str): + Call to action text. + + This field is a member of `oneof`_ ``_call_to_action_text``. + lead_form_only (bool): + Boolean option that indicates if this ad must + be served with lead form. + + This field is a member of `oneof`_ ``_lead_form_only``. + """ + + marketing_images = proto.RepeatedField( + proto.MESSAGE, number=1, message=ad_asset.AdImageAsset, + ) + square_marketing_images = proto.RepeatedField( + proto.MESSAGE, number=2, message=ad_asset.AdImageAsset, + ) + portrait_marketing_images = proto.RepeatedField( + proto.MESSAGE, number=3, message=ad_asset.AdImageAsset, + ) + logo_images = proto.RepeatedField( + proto.MESSAGE, number=4, message=ad_asset.AdImageAsset, + ) + headlines = proto.RepeatedField( + proto.MESSAGE, number=5, message=ad_asset.AdTextAsset, + ) + descriptions = proto.RepeatedField( + proto.MESSAGE, number=6, message=ad_asset.AdTextAsset, + ) + business_name = proto.Field(proto.STRING, number=7, optional=True,) + call_to_action_text = proto.Field(proto.STRING, number=8, optional=True,) + lead_form_only = proto.Field(proto.BOOL, number=9, optional=True,) + + +class DiscoveryCarouselAdInfo(proto.Message): + r"""A discovery carousel ad. + + Attributes: + business_name (str): + Required. The Advertiser/brand name. + logo_image (google.ads.googleads.v12.common.types.AdImageAsset): + Required. Logo image to be used in the ad. + The minimum size is 128x128 and the aspect ratio + must be 1:1(+-1%). + headline (google.ads.googleads.v12.common.types.AdTextAsset): + Required. Headline of the ad. + description (google.ads.googleads.v12.common.types.AdTextAsset): + Required. The descriptive text of the ad. + call_to_action_text (str): + Call to action text. + carousel_cards (Sequence[google.ads.googleads.v12.common.types.AdDiscoveryCarouselCardAsset]): + Required. Carousel cards that will display + with the ad. Min 2 max 10. + """ + + business_name = proto.Field(proto.STRING, number=1,) + logo_image = proto.Field( + proto.MESSAGE, number=2, message=ad_asset.AdImageAsset, + ) + headline = proto.Field( + proto.MESSAGE, number=3, message=ad_asset.AdTextAsset, + ) + description = proto.Field( + proto.MESSAGE, number=4, message=ad_asset.AdTextAsset, + ) + call_to_action_text = proto.Field(proto.STRING, number=5,) + carousel_cards = proto.RepeatedField( + proto.MESSAGE, number=6, message=ad_asset.AdDiscoveryCarouselCardAsset, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/asset_policy.py b/google/ads/googleads/v12/common/types/asset_policy.py new file mode 100644 index 000000000..f6c1352a5 --- /dev/null +++ b/google/ads/googleads/v12/common/types/asset_policy.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"AdAssetPolicySummary",}, +) + + +class AdAssetPolicySummary(proto.Message): + r"""Contains policy information for an asset inside an ad. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + The list of policy findings for this asset. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Where in the review process this asset. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + The overall approval status of this asset, + which is calculated based on the status of its + individual policy topic entries. + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + review_status = proto.Field( + proto.ENUM, + number=2, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/asset_set_types.py b/google/ads/googleads/v12/common/types/asset_set_types.py new file mode 100644 index 000000000..86c85e808 --- /dev/null +++ b/google/ads/googleads/v12/common/types/asset_set_types.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import chain_relationship_type +from google.ads.googleads.v12.enums.types import ( + location_ownership_type as gage_location_ownership_type, +) +from google.ads.googleads.v12.enums.types import location_string_filter_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "LocationSet", + "BusinessProfileLocationSet", + "ChainSet", + "ChainFilter", + "MapsLocationSet", + "MapsLocationInfo", + "BusinessProfileLocationGroup", + "DynamicBusinessProfileLocationGroupFilter", + "BusinessProfileBusinessNameFilter", + "ChainLocationGroup", + }, +) + + +class LocationSet(proto.Message): + r"""Data related to location set. One of the Google Business + Profile (previously known as Google My Business) data, Chain + data, and map location data need to be specified. + + 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: + location_ownership_type (google.ads.googleads.v12.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): + Required. Immutable. Location Ownership Type + (owned location or affiliate location). + business_profile_location_set (google.ads.googleads.v12.common.types.BusinessProfileLocationSet): + Data used to configure a location set + populated from Google Business Profile + locations. + + This field is a member of `oneof`_ ``source``. + chain_location_set (google.ads.googleads.v12.common.types.ChainSet): + Data used to configure a location on chain + set populated with the specified chains. + + This field is a member of `oneof`_ ``source``. + maps_location_set (google.ads.googleads.v12.common.types.MapsLocationSet): + Only set if locations are synced based on + selected maps locations + + This field is a member of `oneof`_ ``source``. + """ + + location_ownership_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_location_ownership_type.LocationOwnershipTypeEnum.LocationOwnershipType, + ) + business_profile_location_set = proto.Field( + proto.MESSAGE, + number=1, + oneof="source", + message="BusinessProfileLocationSet", + ) + chain_location_set = proto.Field( + proto.MESSAGE, number=2, oneof="source", message="ChainSet", + ) + maps_location_set = proto.Field( + proto.MESSAGE, number=5, oneof="source", message="MapsLocationSet", + ) + + +class BusinessProfileLocationSet(proto.Message): + r"""Data used to configure a location set populated from Google + Business Profile locations. + Different types of filters are AND'ed together, if they are + specified. + + Attributes: + http_authorization_token (str): + Required. Immutable. The HTTP authorization + token used to obtain authorization. + email_address (str): + Required. Immutable. Email address of a + Google Business Profile account or email address + of a manager of the Google Business Profile + account. + business_name_filter (str): + Used to filter Google Business Profile + listings by business name. If businessNameFilter + is set, only listings with a matching business + name are candidates to be sync'd into Assets. + label_filters (Sequence[str]): + Used to filter Google Business Profile + listings by labels. If entries exist in + labelFilters, only listings that have any of the + labels set are candidates to be synchronized + into Assets. If no entries exist in + labelFilters, then all listings are candidates + for syncing. Label filters are OR'ed together. + listing_id_filters (Sequence[int]): + Used to filter Google Business Profile + listings by listing id. If entries exist in + listingIdFilters, only listings specified by the + filters are candidates to be synchronized into + Assets. If no entries exist in listingIdFilters, + then all listings are candidates for syncing. + Listing ID filters are OR'ed together. + business_account_id (str): + Immutable. The account ID of the managed + business whose locations are to be used. If this + field is not set, then all businesses accessible + by the user (specified by the emailAddress) are + used. + """ + + http_authorization_token = proto.Field(proto.STRING, number=1,) + email_address = proto.Field(proto.STRING, number=2,) + business_name_filter = proto.Field(proto.STRING, number=3,) + label_filters = proto.RepeatedField(proto.STRING, number=4,) + listing_id_filters = proto.RepeatedField(proto.INT64, number=5,) + business_account_id = proto.Field(proto.STRING, number=6,) + + +class ChainSet(proto.Message): + r"""Data used to configure a location set populated with the + specified chains. + + Attributes: + relationship_type (google.ads.googleads.v12.enums.types.ChainRelationshipTypeEnum.ChainRelationshipType): + Required. Immutable. Relationship type the + specified chains have with this advertiser. + chains (Sequence[google.ads.googleads.v12.common.types.ChainFilter]): + Required. A list of chain level filters, all + filters are OR'ed together. + """ + + relationship_type = proto.Field( + proto.ENUM, + number=1, + enum=chain_relationship_type.ChainRelationshipTypeEnum.ChainRelationshipType, + ) + chains = proto.RepeatedField( + proto.MESSAGE, number=2, message="ChainFilter", + ) + + +class ChainFilter(proto.Message): + r"""One chain level filter on location in a feed item set. + The filtering logic among all the fields is AND. + + Attributes: + chain_id (int): + Required. Used to filter chain locations by + chain id. Only chain locations that belong to + the specified chain will be in the asset set. + location_attributes (Sequence[str]): + Used to filter chain locations by location + attributes. Only chain locations that belong to + all of the specified attribute(s) will be in the + asset set. If this field is empty, it means no + filtering on this field. + """ + + chain_id = proto.Field(proto.INT64, number=1,) + location_attributes = proto.RepeatedField(proto.STRING, number=2,) + + +class MapsLocationSet(proto.Message): + r"""Wrapper for multiple maps location sync data + + Attributes: + maps_locations (Sequence[google.ads.googleads.v12.common.types.MapsLocationInfo]): + Required. A list of maps location info that + user manually synced in. + """ + + maps_locations = proto.RepeatedField( + proto.MESSAGE, number=1, message="MapsLocationInfo", + ) + + +class MapsLocationInfo(proto.Message): + r"""Wrapper for place ids + + Attributes: + place_id (str): + Place ID of the Maps location. + """ + + place_id = proto.Field(proto.STRING, number=1,) + + +class BusinessProfileLocationGroup(proto.Message): + r"""Information about a Business Profile dynamic location group. Only + applicable if the sync level AssetSet's type is LOCATION_SYNC and + sync source is Business Profile. + + Attributes: + dynamic_business_profile_location_group_filter (google.ads.googleads.v12.common.types.DynamicBusinessProfileLocationGroupFilter): + Filter for dynamic Business Profile location + sets. + """ + + dynamic_business_profile_location_group_filter = proto.Field( + proto.MESSAGE, + number=1, + message="DynamicBusinessProfileLocationGroupFilter", + ) + + +class DynamicBusinessProfileLocationGroupFilter(proto.Message): + r"""Represents a filter on Business Profile locations in an asset + set. If multiple filters are provided, they are AND'ed together. + + Attributes: + label_filters (Sequence[str]): + Used to filter Business Profile locations by + label. Only locations that have any of the + listed labels will be in the asset set. Label + filters are OR'ed together. + business_name_filter (google.ads.googleads.v12.common.types.BusinessProfileBusinessNameFilter): + Used to filter Business Profile locations by + business name. + + This field is a member of `oneof`_ ``_business_name_filter``. + listing_id_filters (Sequence[int]): + Used to filter Business Profile locations by + listing ids. + """ + + label_filters = proto.RepeatedField(proto.STRING, number=1,) + business_name_filter = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message="BusinessProfileBusinessNameFilter", + ) + listing_id_filters = proto.RepeatedField(proto.INT64, number=3,) + + +class BusinessProfileBusinessNameFilter(proto.Message): + r"""Business Profile location group business name filter. + + Attributes: + business_name (str): + Business name string to use for filtering. + filter_type (google.ads.googleads.v12.enums.types.LocationStringFilterTypeEnum.LocationStringFilterType): + The type of string matching to use when filtering with + business_name. + """ + + business_name = proto.Field(proto.STRING, number=1,) + filter_type = proto.Field( + proto.ENUM, + number=2, + enum=location_string_filter_type.LocationStringFilterTypeEnum.LocationStringFilterType, + ) + + +class ChainLocationGroup(proto.Message): + r"""Represents information about a Chain dynamic location group. Only + applicable if the sync level AssetSet's type is LOCATION_SYNC and + sync source is chain. + + Attributes: + dynamic_chain_location_group_filters (Sequence[google.ads.googleads.v12.common.types.ChainFilter]): + Used to filter chain locations by chain ids. + Only Locations that belong to the specified + chain(s) will be in the asset set. + """ + + dynamic_chain_location_group_filters = proto.RepeatedField( + proto.MESSAGE, number=1, message="ChainFilter", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/asset_types.py b/google/ads/googleads/v12/common/types/asset_types.py new file mode 100644 index 000000000..74d9fc1f1 --- /dev/null +++ b/google/ads/googleads/v12/common/types/asset_types.py @@ -0,0 +1,1559 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.common.types import feed_common +from google.ads.googleads.v12.enums.types import ( + call_conversion_reporting_state as gage_call_conversion_reporting_state, +) +from google.ads.googleads.v12.enums.types import ( + call_to_action_type as gage_call_to_action_type, +) +from google.ads.googleads.v12.enums.types import lead_form_call_to_action_type +from google.ads.googleads.v12.enums.types import lead_form_desired_intent +from google.ads.googleads.v12.enums.types import lead_form_field_user_input_type +from google.ads.googleads.v12.enums.types import ( + lead_form_post_submit_call_to_action_type, +) +from google.ads.googleads.v12.enums.types import ( + location_ownership_type as gage_location_ownership_type, +) +from google.ads.googleads.v12.enums.types import mime_type as gage_mime_type +from google.ads.googleads.v12.enums.types import mobile_app_vendor +from google.ads.googleads.v12.enums.types import price_extension_price_qualifier +from google.ads.googleads.v12.enums.types import price_extension_price_unit +from google.ads.googleads.v12.enums.types import price_extension_type +from google.ads.googleads.v12.enums.types import ( + promotion_extension_discount_modifier, +) +from google.ads.googleads.v12.enums.types import promotion_extension_occasion + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "YoutubeVideoAsset", + "MediaBundleAsset", + "ImageAsset", + "ImageDimension", + "TextAsset", + "LeadFormAsset", + "LeadFormField", + "LeadFormCustomQuestionField", + "LeadFormSingleChoiceAnswers", + "LeadFormDeliveryMethod", + "WebhookDelivery", + "BookOnGoogleAsset", + "PromotionAsset", + "CalloutAsset", + "StructuredSnippetAsset", + "SitelinkAsset", + "PageFeedAsset", + "DynamicEducationAsset", + "MobileAppAsset", + "HotelCalloutAsset", + "CallAsset", + "PriceAsset", + "PriceOffering", + "CallToActionAsset", + "DynamicRealEstateAsset", + "DynamicCustomAsset", + "DynamicHotelsAndRentalsAsset", + "DynamicFlightsAsset", + "DiscoveryCarouselCardAsset", + "DynamicTravelAsset", + "DynamicLocalAsset", + "DynamicJobsAsset", + "LocationAsset", + "BusinessProfileLocation", + }, +) + + +class YoutubeVideoAsset(proto.Message): + r"""A YouTube asset. + + Attributes: + youtube_video_id (str): + YouTube video id. This is the 11 character + string value used in the YouTube video URL. + + This field is a member of `oneof`_ ``_youtube_video_id``. + youtube_video_title (str): + YouTube video title. + """ + + youtube_video_id = proto.Field(proto.STRING, number=2, optional=True,) + youtube_video_title = proto.Field(proto.STRING, number=3,) + + +class MediaBundleAsset(proto.Message): + r"""A MediaBundle asset. + + Attributes: + data (bytes): + Media bundle (ZIP file) asset data. The + format of the uploaded ZIP file depends on the + ad field where it will be used. For more + information on the format, see the documentation + of the ad field where you plan on using the + MediaBundleAsset. This field is mutate only. + + This field is a member of `oneof`_ ``_data``. + """ + + data = proto.Field(proto.BYTES, number=2, optional=True,) + + +class ImageAsset(proto.Message): + r"""An Image asset. + + Attributes: + data (bytes): + The raw bytes data of an image. This field is + mutate only. + + This field is a member of `oneof`_ ``_data``. + file_size (int): + File size of the image asset in bytes. + + This field is a member of `oneof`_ ``_file_size``. + mime_type (google.ads.googleads.v12.enums.types.MimeTypeEnum.MimeType): + MIME type of the image asset. + full_size (google.ads.googleads.v12.common.types.ImageDimension): + Metadata for this image at its original size. + """ + + data = proto.Field(proto.BYTES, number=5, optional=True,) + file_size = proto.Field(proto.INT64, number=6, optional=True,) + mime_type = proto.Field( + proto.ENUM, number=3, enum=gage_mime_type.MimeTypeEnum.MimeType, + ) + full_size = proto.Field(proto.MESSAGE, number=4, message="ImageDimension",) + + +class ImageDimension(proto.Message): + r"""Metadata for an image at a certain size, either original or + resized. + + Attributes: + height_pixels (int): + Height of the image. + + This field is a member of `oneof`_ ``_height_pixels``. + width_pixels (int): + Width of the image. + + This field is a member of `oneof`_ ``_width_pixels``. + url (str): + A URL that returns the image with this height + and width. + + This field is a member of `oneof`_ ``_url``. + """ + + height_pixels = proto.Field(proto.INT64, number=4, optional=True,) + width_pixels = proto.Field(proto.INT64, number=5, optional=True,) + url = proto.Field(proto.STRING, number=6, optional=True,) + + +class TextAsset(proto.Message): + r"""A Text asset. + + Attributes: + text (str): + Text content of the text asset. + + This field is a member of `oneof`_ ``_text``. + """ + + text = proto.Field(proto.STRING, number=2, optional=True,) + + +class LeadFormAsset(proto.Message): + r"""A Lead Form asset. + + Attributes: + business_name (str): + Required. The name of the business being + advertised. + call_to_action_type (google.ads.googleads.v12.enums.types.LeadFormCallToActionTypeEnum.LeadFormCallToActionType): + Required. Pre-defined display text that + encourages user to expand the form. + call_to_action_description (str): + Required. Text giving a clear value + proposition of what users expect once they + expand the form. + headline (str): + Required. Headline of the expanded form to + describe what the form is asking for or + facilitating. + description (str): + Required. Detailed description of the + expanded form to describe what the form is + asking for or facilitating. + privacy_policy_url (str): + Required. Link to a page describing the + policy on how the collected data is handled by + the advertiser/business. + post_submit_headline (str): + Headline of text shown after form submission + that describes how the advertiser will follow up + with the user. + + This field is a member of `oneof`_ ``_post_submit_headline``. + post_submit_description (str): + Detailed description shown after form + submission that describes how the advertiser + will follow up with the user. + + This field is a member of `oneof`_ ``_post_submit_description``. + fields (Sequence[google.ads.googleads.v12.common.types.LeadFormField]): + Ordered list of input fields. This field can + be updated by reordering questions, but not by + adding or removing questions. + custom_question_fields (Sequence[google.ads.googleads.v12.common.types.LeadFormCustomQuestionField]): + Ordered list of custom question fields. + delivery_methods (Sequence[google.ads.googleads.v12.common.types.LeadFormDeliveryMethod]): + Configured methods for collected lead data to + be delivered to advertiser. Only one method + typed as WebhookDelivery can be configured. + post_submit_call_to_action_type (google.ads.googleads.v12.enums.types.LeadFormPostSubmitCallToActionTypeEnum.LeadFormPostSubmitCallToActionType): + Pre-defined display text that encourages user + action after the form is submitted. + background_image_asset (str): + Asset resource name of the background image. + The minimum size is 600x314 and the aspect ratio + must be 1.91:1 (+-1%). + + This field is a member of `oneof`_ ``_background_image_asset``. + desired_intent (google.ads.googleads.v12.enums.types.LeadFormDesiredIntentEnum.LeadFormDesiredIntent): + Chosen intent for the lead form, for example, + more volume or more qualified. + custom_disclosure (str): + Custom disclosure shown along with Google + disclaimer on the lead form. Accessible to + allowed customers only. + + This field is a member of `oneof`_ ``_custom_disclosure``. + """ + + business_name = proto.Field(proto.STRING, number=10,) + call_to_action_type = proto.Field( + proto.ENUM, + number=17, + enum=lead_form_call_to_action_type.LeadFormCallToActionTypeEnum.LeadFormCallToActionType, + ) + call_to_action_description = proto.Field(proto.STRING, number=18,) + headline = proto.Field(proto.STRING, number=12,) + description = proto.Field(proto.STRING, number=13,) + privacy_policy_url = proto.Field(proto.STRING, number=14,) + post_submit_headline = proto.Field(proto.STRING, number=15, optional=True,) + post_submit_description = proto.Field( + proto.STRING, number=16, optional=True, + ) + fields = proto.RepeatedField( + proto.MESSAGE, number=8, message="LeadFormField", + ) + custom_question_fields = proto.RepeatedField( + proto.MESSAGE, number=23, message="LeadFormCustomQuestionField", + ) + delivery_methods = proto.RepeatedField( + proto.MESSAGE, number=9, message="LeadFormDeliveryMethod", + ) + post_submit_call_to_action_type = proto.Field( + proto.ENUM, + number=19, + enum=lead_form_post_submit_call_to_action_type.LeadFormPostSubmitCallToActionTypeEnum.LeadFormPostSubmitCallToActionType, + ) + background_image_asset = proto.Field( + proto.STRING, number=20, optional=True, + ) + desired_intent = proto.Field( + proto.ENUM, + number=21, + enum=lead_form_desired_intent.LeadFormDesiredIntentEnum.LeadFormDesiredIntent, + ) + custom_disclosure = proto.Field(proto.STRING, number=22, optional=True,) + + +class LeadFormField(proto.Message): + r"""One input field instance within a form. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + input_type (google.ads.googleads.v12.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): + Describes the input type, which may be a + predefined type such as "full name" or a + pre-vetted question like "What kind of vehicle + do you have?". + single_choice_answers (google.ads.googleads.v12.common.types.LeadFormSingleChoiceAnswers): + Answer configuration for a single choice + question. Can be set only for pre-vetted + question fields. Minimum of 2 answers required + and maximum of 12 allowed. + + This field is a member of `oneof`_ ``answers``. + """ + + input_type = proto.Field( + proto.ENUM, + number=1, + enum=lead_form_field_user_input_type.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType, + ) + single_choice_answers = proto.Field( + proto.MESSAGE, + number=2, + oneof="answers", + message="LeadFormSingleChoiceAnswers", + ) + + +class LeadFormCustomQuestionField(proto.Message): + r"""One custom question input field instance within a form. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + custom_question_text (str): + The exact custom question field text (for + example, "What kind of vehicle do you have?"). + single_choice_answers (google.ads.googleads.v12.common.types.LeadFormSingleChoiceAnswers): + Answer configuration for a single choice + question. Minimum of 2 answers and maximum of 12 + allowed. + + This field is a member of `oneof`_ ``answers``. + """ + + custom_question_text = proto.Field(proto.STRING, number=1,) + single_choice_answers = proto.Field( + proto.MESSAGE, + number=2, + oneof="answers", + message="LeadFormSingleChoiceAnswers", + ) + + +class LeadFormSingleChoiceAnswers(proto.Message): + r"""Defines possible answers for a single choice question, + usually presented as a single-choice drop-down list. + + Attributes: + answers (Sequence[str]): + List of choices for a single question field. + The order of entries defines UI order. Minimum + of 2 answers required and maximum of 12 allowed. + """ + + answers = proto.RepeatedField(proto.STRING, number=1,) + + +class LeadFormDeliveryMethod(proto.Message): + r"""A configuration of how leads are delivered to the advertiser. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + webhook (google.ads.googleads.v12.common.types.WebhookDelivery): + Webhook method of delivery. + + This field is a member of `oneof`_ ``delivery_details``. + """ + + webhook = proto.Field( + proto.MESSAGE, + number=1, + oneof="delivery_details", + message="WebhookDelivery", + ) + + +class WebhookDelivery(proto.Message): + r"""Google notifies the advertiser of leads by making HTTP calls + to an endpoint they specify. The requests contain JSON matching + a schema that Google publishes as part of form ads + documentation. + + Attributes: + advertiser_webhook_url (str): + Webhook url specified by advertiser to send + the lead. + + This field is a member of `oneof`_ ``_advertiser_webhook_url``. + google_secret (str): + Anti-spoofing secret set by the advertiser as + part of the webhook payload. + + This field is a member of `oneof`_ ``_google_secret``. + payload_schema_version (int): + The schema version that this delivery + instance will use. + + This field is a member of `oneof`_ ``_payload_schema_version``. + """ + + advertiser_webhook_url = proto.Field(proto.STRING, number=4, optional=True,) + google_secret = proto.Field(proto.STRING, number=5, optional=True,) + payload_schema_version = proto.Field(proto.INT64, number=6, optional=True,) + + +class BookOnGoogleAsset(proto.Message): + r"""A Book on Google asset. Used to redirect user to book through + Google. Book on Google will change the redirect url to book + directly through Google. + + """ + + +class PromotionAsset(proto.Message): + r"""A Promotion asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + promotion_target (str): + Required. A freeform description of what the + promotion is targeting. + discount_modifier (google.ads.googleads.v12.enums.types.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier): + A modifier for qualification of the discount. + redemption_start_date (str): + Start date of when the promotion is eligible + to be redeemed, in yyyy-MM-dd format. + redemption_end_date (str): + Last date of when the promotion is eligible + to be redeemed, in yyyy-MM-dd format. + occasion (google.ads.googleads.v12.enums.types.PromotionExtensionOccasionEnum.PromotionExtensionOccasion): + The occasion the promotion was intended for. + If an occasion is set, the redemption window + will need to fall within the date range + associated with the occasion. + language_code (str): + The language of the promotion. + Represented as BCP 47 language tag. + start_date (str): + Start date of when this asset is effective + and can begin serving, in yyyy-MM-dd format. + end_date (str): + Last date of when this asset is effective and + still serving, in yyyy-MM-dd format. + ad_schedule_targets (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + List of non-overlapping schedules specifying + all time intervals for which the asset may + serve. There can be a maximum of 6 schedules per + day, 42 in total. + percent_off (int): + Percentage off discount in the promotion. 1,000,000 = 100%. + Either this or money_amount_off is required. + + This field is a member of `oneof`_ ``discount_type``. + money_amount_off (google.ads.googleads.v12.common.types.Money): + Money amount off for discount in the promotion. Either this + or percent_off is required. + + This field is a member of `oneof`_ ``discount_type``. + promotion_code (str): + A code the user should use in order to be + eligible for the promotion. + + This field is a member of `oneof`_ ``promotion_trigger``. + orders_over_amount (google.ads.googleads.v12.common.types.Money): + The amount the total order needs to be for + the user to be eligible for the promotion. + + This field is a member of `oneof`_ ``promotion_trigger``. + """ + + promotion_target = proto.Field(proto.STRING, number=1,) + discount_modifier = proto.Field( + proto.ENUM, + number=2, + enum=promotion_extension_discount_modifier.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier, + ) + redemption_start_date = proto.Field(proto.STRING, number=7,) + redemption_end_date = proto.Field(proto.STRING, number=8,) + occasion = proto.Field( + proto.ENUM, + number=9, + enum=promotion_extension_occasion.PromotionExtensionOccasionEnum.PromotionExtensionOccasion, + ) + language_code = proto.Field(proto.STRING, number=10,) + start_date = proto.Field(proto.STRING, number=11,) + end_date = proto.Field(proto.STRING, number=12,) + ad_schedule_targets = proto.RepeatedField( + proto.MESSAGE, number=13, message=criteria.AdScheduleInfo, + ) + percent_off = proto.Field(proto.INT64, number=3, oneof="discount_type",) + money_amount_off = proto.Field( + proto.MESSAGE, + number=4, + oneof="discount_type", + message=feed_common.Money, + ) + promotion_code = proto.Field( + proto.STRING, number=5, oneof="promotion_trigger", + ) + orders_over_amount = proto.Field( + proto.MESSAGE, + number=6, + oneof="promotion_trigger", + message=feed_common.Money, + ) + + +class CalloutAsset(proto.Message): + r"""A Callout asset. + + Attributes: + callout_text (str): + Required. The callout text. + The length of this string should be between 1 + and 25, inclusive. + start_date (str): + Start date of when this asset is effective + and can begin serving, in yyyy-MM-dd format. + end_date (str): + Last date of when this asset is effective and + still serving, in yyyy-MM-dd format. + ad_schedule_targets (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + List of non-overlapping schedules specifying + all time intervals for which the asset may + serve. There can be a maximum of 6 schedules per + day, 42 in total. + """ + + callout_text = proto.Field(proto.STRING, number=1,) + start_date = proto.Field(proto.STRING, number=2,) + end_date = proto.Field(proto.STRING, number=3,) + ad_schedule_targets = proto.RepeatedField( + proto.MESSAGE, number=4, message=criteria.AdScheduleInfo, + ) + + +class StructuredSnippetAsset(proto.Message): + r"""A Structured Snippet asset. + + Attributes: + header (str): + Required. The header of the snippet. + This string should be one of the predefined + values at + https://developers.google.com/google-ads/api/reference/data/structured-snippet-headers + values (Sequence[str]): + Required. The values in the snippet. + The size of this collection should be between 3 + and 10, inclusive. The length of each value + should be between 1 and 25 characters, + inclusive. + """ + + header = proto.Field(proto.STRING, number=1,) + values = proto.RepeatedField(proto.STRING, number=2,) + + +class SitelinkAsset(proto.Message): + r"""A Sitelink asset. + + Attributes: + link_text (str): + Required. URL display text for the sitelink. + The length of this string should be between 1 + and 25, inclusive. + description1 (str): + First line of the description for the + sitelink. If set, the length should be between 1 + and 35, inclusive, and description2 must also be + set. + description2 (str): + Second line of the description for the + sitelink. If set, the length should be between 1 + and 35, inclusive, and description1 must also be + set. + start_date (str): + Start date of when this asset is effective + and can begin serving, in yyyy-MM-dd format. + end_date (str): + Last date of when this asset is effective and + still serving, in yyyy-MM-dd format. + ad_schedule_targets (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + List of non-overlapping schedules specifying + all time intervals for which the asset may + serve. There can be a maximum of 6 schedules per + day, 42 in total. + """ + + link_text = proto.Field(proto.STRING, number=1,) + description1 = proto.Field(proto.STRING, number=2,) + description2 = proto.Field(proto.STRING, number=3,) + start_date = proto.Field(proto.STRING, number=4,) + end_date = proto.Field(proto.STRING, number=5,) + ad_schedule_targets = proto.RepeatedField( + proto.MESSAGE, number=6, message=criteria.AdScheduleInfo, + ) + + +class PageFeedAsset(proto.Message): + r"""A Page Feed asset. + + Attributes: + page_url (str): + Required. The webpage that advertisers want + to target. + labels (Sequence[str]): + Labels used to group the page urls. + """ + + page_url = proto.Field(proto.STRING, number=1,) + labels = proto.RepeatedField(proto.STRING, number=2,) + + +class DynamicEducationAsset(proto.Message): + r"""A Dynamic Education asset. + + Attributes: + program_id (str): + Required. Program ID which can be any + sequence of letters and digits, and must be + unique and match the values of remarketing tag. + Required. + location_id (str): + Location ID which can be any sequence of + letters and digits and must be unique. + program_name (str): + Required. Program name, for example, Nursing. + Required. + subject (str): + Subject of study, for example, Health. + program_description (str): + Program description, for example, Nursing + Certification. + school_name (str): + School name, for example, Mountain View + School of Nursing. + address (str): + School address which can be specified in one + of the following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403 + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Nursing + certification, Health, Mountain View. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + similar_program_ids (Sequence[str]): + Similar program IDs. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + thumbnail_image_url (str): + Thumbnail image url, for example, + http://www.example.com/thumbnail.png. The + thumbnail image will not be uploaded as image + asset. + image_url (str): + Image url, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + """ + + program_id = proto.Field(proto.STRING, number=1,) + location_id = proto.Field(proto.STRING, number=2,) + program_name = proto.Field(proto.STRING, number=3,) + subject = proto.Field(proto.STRING, number=4,) + program_description = proto.Field(proto.STRING, number=5,) + school_name = proto.Field(proto.STRING, number=6,) + address = proto.Field(proto.STRING, number=7,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=8,) + android_app_link = proto.Field(proto.STRING, number=9,) + similar_program_ids = proto.RepeatedField(proto.STRING, number=10,) + ios_app_link = proto.Field(proto.STRING, number=11,) + ios_app_store_id = proto.Field(proto.INT64, number=12,) + thumbnail_image_url = proto.Field(proto.STRING, number=13,) + image_url = proto.Field(proto.STRING, number=14,) + + +class MobileAppAsset(proto.Message): + r"""An asset representing a mobile app. + + Attributes: + app_id (str): + Required. A string that uniquely identifies a + mobile application. It should just contain the + platform native id, like "com.android.ebay" for + Android or "12345689" for iOS. + app_store (google.ads.googleads.v12.enums.types.MobileAppVendorEnum.MobileAppVendor): + Required. The application store that + distributes this specific app. + link_text (str): + Required. The visible text displayed when the + link is rendered in an ad. The length of this + string should be between 1 and 25, inclusive. + start_date (str): + Start date of when this asset is effective + and can begin serving, in yyyy-MM-dd format. + end_date (str): + Last date of when this asset is effective and + still serving, in yyyy-MM-dd format. + """ + + app_id = proto.Field(proto.STRING, number=1,) + app_store = proto.Field( + proto.ENUM, + number=2, + enum=mobile_app_vendor.MobileAppVendorEnum.MobileAppVendor, + ) + link_text = proto.Field(proto.STRING, number=3,) + start_date = proto.Field(proto.STRING, number=4,) + end_date = proto.Field(proto.STRING, number=5,) + + +class HotelCalloutAsset(proto.Message): + r"""An asset representing a hotel callout. + + Attributes: + text (str): + Required. The text of the hotel callout + asset. The length of this string should be + between 1 and 25, inclusive. + language_code (str): + Required. The language of the hotel callout. + Represented as BCP 47 language tag. + """ + + text = proto.Field(proto.STRING, number=1,) + language_code = proto.Field(proto.STRING, number=2,) + + +class CallAsset(proto.Message): + r"""A Call asset. + + Attributes: + country_code (str): + Required. Two-letter country code of the + phone number. Examples: 'US', 'us'. + phone_number (str): + Required. The advertiser's raw phone number. + Examples: '1234567890', '(123)456-7890' + call_conversion_reporting_state (google.ads.googleads.v12.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): + Indicates whether this CallAsset should use + its own call conversion setting, follow the + account level setting, or disable call + conversion. + call_conversion_action (str): + The conversion action to attribute a call conversion to. If + not set, the default conversion action is used. This field + only has effect if call_conversion_reporting_state is set to + USE_RESOURCE_LEVEL_CALL_CONVERSION_ACTION. + ad_schedule_targets (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + List of non-overlapping schedules specifying + all time intervals for which the asset may + serve. There can be a maximum of 6 schedules per + day, 42 in total. + """ + + country_code = proto.Field(proto.STRING, number=1,) + phone_number = proto.Field(proto.STRING, number=2,) + call_conversion_reporting_state = proto.Field( + proto.ENUM, + number=3, + enum=gage_call_conversion_reporting_state.CallConversionReportingStateEnum.CallConversionReportingState, + ) + call_conversion_action = proto.Field(proto.STRING, number=4,) + ad_schedule_targets = proto.RepeatedField( + proto.MESSAGE, number=5, message=criteria.AdScheduleInfo, + ) + + +class PriceAsset(proto.Message): + r"""An asset representing a list of price offers. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.PriceExtensionTypeEnum.PriceExtensionType): + Required. The type of the price asset. + price_qualifier (google.ads.googleads.v12.enums.types.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier): + The price qualifier of the price asset. + language_code (str): + Required. The language of the price asset. + Represented as BCP 47 language tag. + price_offerings (Sequence[google.ads.googleads.v12.common.types.PriceOffering]): + The price offerings of the price asset. + The size of this collection should be between 3 + and 8, inclusive. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=price_extension_type.PriceExtensionTypeEnum.PriceExtensionType, + ) + price_qualifier = proto.Field( + proto.ENUM, + number=2, + enum=price_extension_price_qualifier.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier, + ) + language_code = proto.Field(proto.STRING, number=3,) + price_offerings = proto.RepeatedField( + proto.MESSAGE, number=4, message="PriceOffering", + ) + + +class PriceOffering(proto.Message): + r"""A single price offering within a PriceAsset. + + Attributes: + header (str): + Required. The header of the price offering. + The length of this string should be between 1 + and 25, inclusive. + description (str): + Required. The description of the price + offering. The length of this string should be + between 1 and 25, inclusive. + price (google.ads.googleads.v12.common.types.Money): + Required. The price value of the price + offering. + unit (google.ads.googleads.v12.enums.types.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit): + The price unit of the price offering. + final_url (str): + Required. The final URL after all cross + domain redirects. + final_mobile_url (str): + The final mobile URL after all cross domain + redirects. + """ + + header = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + price = proto.Field(proto.MESSAGE, number=3, message=feed_common.Money,) + unit = proto.Field( + proto.ENUM, + number=4, + enum=price_extension_price_unit.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit, + ) + final_url = proto.Field(proto.STRING, number=5,) + final_mobile_url = proto.Field(proto.STRING, number=6,) + + +class CallToActionAsset(proto.Message): + r"""A call to action asset. + + Attributes: + call_to_action (google.ads.googleads.v12.enums.types.CallToActionTypeEnum.CallToActionType): + Call to action. + """ + + call_to_action = proto.Field( + proto.ENUM, + number=1, + enum=gage_call_to_action_type.CallToActionTypeEnum.CallToActionType, + ) + + +class DynamicRealEstateAsset(proto.Message): + r"""A dynamic real estate asset. + + Attributes: + listing_id (str): + Required. Listing ID which can be any + sequence of letters and digits, and must be + unique and match the values of remarketing tag. + Required. + listing_name (str): + Required. Listing name, for example, + Boulevard Bungalow. Required. + city_name (str): + City name, for example, Mountain View, + California. + description (str): + Description, for example, 3 beds, 2 baths, + 1568 sq. ft. + address (str): + Address which can be specified in one of the + following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403 + price (str): + Price which can be number followed by the + alphabetic currency code, ISO 4217 standard. Use + '.' as the decimal mark, for example, 200,000.00 + USD. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + property_type (str): + Property type, for example, House. + listing_type (str): + Listing type, for example, For sale. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, For sale; + Houses for sale. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $200,000.00. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + similar_listing_ids (Sequence[str]): + Similar listing IDs. + """ + + listing_id = proto.Field(proto.STRING, number=1,) + listing_name = proto.Field(proto.STRING, number=2,) + city_name = proto.Field(proto.STRING, number=3,) + description = proto.Field(proto.STRING, number=4,) + address = proto.Field(proto.STRING, number=5,) + price = proto.Field(proto.STRING, number=6,) + image_url = proto.Field(proto.STRING, number=7,) + property_type = proto.Field(proto.STRING, number=8,) + listing_type = proto.Field(proto.STRING, number=9,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=10,) + formatted_price = proto.Field(proto.STRING, number=11,) + android_app_link = proto.Field(proto.STRING, number=12,) + ios_app_link = proto.Field(proto.STRING, number=13,) + ios_app_store_id = proto.Field(proto.INT64, number=14,) + similar_listing_ids = proto.RepeatedField(proto.STRING, number=15,) + + +class DynamicCustomAsset(proto.Message): + r"""A dynamic custom asset. + + Attributes: + id (str): + Required. ID which can be any sequence of + letters and digits, and must be unique and match + the values of remarketing tag, for example, + sedan. Required. + id2 (str): + ID2 which can be any sequence of letters and + digits, for example, red. ID sequence (ID + ID2) + must be unique. + item_title (str): + Required. Item title, for example, Mid-size + sedan. Required. + item_subtitle (str): + Item subtitle, for example, At your Mountain + View dealership. + item_description (str): + Item description, for example, Best selling + mid-size car. + item_address (str): + Item address which can be specified in one of + the following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403 + item_category (str): + Item category, for example, Sedans. + price (str): + Price which can be number followed by the + alphabetic currency code, ISO 4217 standard. Use + '.' as the decimal mark, for example, 20,000.00 + USD. + sale_price (str): + Sale price which can be number followed by + the alphabetic currency code, ISO 4217 standard. + Use '.' as the decimal mark, for example, + 15,000.00 USD. Must be less than the 'price' + field. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $20,000.00. + formatted_sale_price (str): + Formatted sale price which can be any + characters. If set, this attribute will be used + instead of 'sale price', for example, On sale + for $15,000.00. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Sedans, 4 + door sedans. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + similar_ids (Sequence[str]): + Similar IDs. + """ + + id = proto.Field(proto.STRING, number=1,) + id2 = proto.Field(proto.STRING, number=2,) + item_title = proto.Field(proto.STRING, number=3,) + item_subtitle = proto.Field(proto.STRING, number=4,) + item_description = proto.Field(proto.STRING, number=5,) + item_address = proto.Field(proto.STRING, number=6,) + item_category = proto.Field(proto.STRING, number=7,) + price = proto.Field(proto.STRING, number=8,) + sale_price = proto.Field(proto.STRING, number=9,) + formatted_price = proto.Field(proto.STRING, number=10,) + formatted_sale_price = proto.Field(proto.STRING, number=11,) + image_url = proto.Field(proto.STRING, number=12,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=13,) + android_app_link = proto.Field(proto.STRING, number=14,) + ios_app_link = proto.Field(proto.STRING, number=16,) + ios_app_store_id = proto.Field(proto.INT64, number=17,) + similar_ids = proto.RepeatedField(proto.STRING, number=15,) + + +class DynamicHotelsAndRentalsAsset(proto.Message): + r"""A dynamic hotels and rentals asset. + + Attributes: + property_id (str): + Required. Property ID which can be any + sequence of letters and digits, and must be + unique and match the values of remarketing tag. + Required. + property_name (str): + Required. Property name, for example, + Mountain View Hotel. Required. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + destination_name (str): + Destination name, for example, Downtown + Mountain View. + description (str): + Description, for example, Close to SJC + Airport. + price (str): + Price which can be number followed by the + alphabetic currency code, ISO 4217 standard. Use + '.' as the decimal mark, for example, 100.00 + USD. + sale_price (str): + ISO 4217 standard. Use '.' as the decimal + mark, for example, 80.00 USD. Must be less than + the 'price' field. + star_rating (int): + Star rating. Must be a number between 1 to 5, + inclusive. + category (str): + Category, for example, Hotel suite. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Mountain + View "Hotels", South Bay hotels. + address (str): + Address which can be specified in one of the + following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403 + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $100.00. + formatted_sale_price (str): + Formatted sale price which can be any + characters. If set, this attribute will be used + instead of 'sale price', for example, On sale + for $80.00. + similar_property_ids (Sequence[str]): + Similar property IDs. + """ + + property_id = proto.Field(proto.STRING, number=1,) + property_name = proto.Field(proto.STRING, number=2,) + image_url = proto.Field(proto.STRING, number=3,) + destination_name = proto.Field(proto.STRING, number=4,) + description = proto.Field(proto.STRING, number=5,) + price = proto.Field(proto.STRING, number=6,) + sale_price = proto.Field(proto.STRING, number=7,) + star_rating = proto.Field(proto.INT64, number=8,) + category = proto.Field(proto.STRING, number=9,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=10,) + address = proto.Field(proto.STRING, number=11,) + android_app_link = proto.Field(proto.STRING, number=12,) + ios_app_link = proto.Field(proto.STRING, number=13,) + ios_app_store_id = proto.Field(proto.INT64, number=14,) + formatted_price = proto.Field(proto.STRING, number=15,) + formatted_sale_price = proto.Field(proto.STRING, number=16,) + similar_property_ids = proto.RepeatedField(proto.STRING, number=17,) + + +class DynamicFlightsAsset(proto.Message): + r"""A dynamic flights asset. + + Attributes: + destination_id (str): + Required. Destination ID which can be any + sequence of letters and digits, and must be + unique and match the values of remarketing tag. + Required. + origin_id (str): + Origin ID which can be any sequence of + letters and digits. The ID sequence (destination + ID + origin ID) must be unique. + flight_description (str): + Required. Flight description, for example, + Book your ticket. Required. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + destination_name (str): + Destination name, for example, Paris. + origin_name (str): + Origin name, for example, London. + flight_price (str): + Flight price which can be number followed by + the alphabetic currency code, ISO 4217 standard. + Use '.' as the decimal mark, for example, 100.00 + USD. + flight_sale_price (str): + Flight sale price which can be number followed by the + alphabetic currency code, ISO 4217 standard. Use '.' as the + decimal mark, for example, 80.00 USD. Must be less than the + 'flight_price' field. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $100.00. + formatted_sale_price (str): + Formatted sale price which can be any + characters. If set, this attribute will be used + instead of 'sale price', for example, On sale + for $80.00. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + similar_destination_ids (Sequence[str]): + Similar destination IDs, for example, + PAR,LON. + custom_mapping (str): + A custom field which can be multiple key to values mapping + separated by delimiters (",", "|" and ":"), in the forms of + ": , , ... , \| : + , ... , \| ... \| : , ... + ," for example, wifi: most \| aircraft: 320, 77W \| + flights: 42 \| legroom: 32". + """ + + destination_id = proto.Field(proto.STRING, number=1,) + origin_id = proto.Field(proto.STRING, number=2,) + flight_description = proto.Field(proto.STRING, number=3,) + image_url = proto.Field(proto.STRING, number=4,) + destination_name = proto.Field(proto.STRING, number=5,) + origin_name = proto.Field(proto.STRING, number=6,) + flight_price = proto.Field(proto.STRING, number=7,) + flight_sale_price = proto.Field(proto.STRING, number=8,) + formatted_price = proto.Field(proto.STRING, number=9,) + formatted_sale_price = proto.Field(proto.STRING, number=10,) + android_app_link = proto.Field(proto.STRING, number=11,) + ios_app_link = proto.Field(proto.STRING, number=12,) + ios_app_store_id = proto.Field(proto.INT64, number=13,) + similar_destination_ids = proto.RepeatedField(proto.STRING, number=14,) + custom_mapping = proto.Field(proto.STRING, number=15,) + + +class DiscoveryCarouselCardAsset(proto.Message): + r"""A Discovery Carousel Card asset. + + Attributes: + marketing_image_asset (str): + Asset resource name of the associated 1.91:1 + marketing image. This and/or square marketing + image asset is required. + square_marketing_image_asset (str): + Asset resource name of the associated square + marketing image. This and/or a marketing image + asset is required. + portrait_marketing_image_asset (str): + Asset resource name of the associated 4:5 + portrait marketing image. + headline (str): + Required. Headline of the carousel card. + call_to_action_text (str): + Call to action text. + """ + + marketing_image_asset = proto.Field(proto.STRING, number=1,) + square_marketing_image_asset = proto.Field(proto.STRING, number=2,) + portrait_marketing_image_asset = proto.Field(proto.STRING, number=3,) + headline = proto.Field(proto.STRING, number=4,) + call_to_action_text = proto.Field(proto.STRING, number=5,) + + +class DynamicTravelAsset(proto.Message): + r"""A dynamic travel asset. + + Attributes: + destination_id (str): + Required. Destination ID which can be any + sequence of letters and digits, and must be + unique and match the values of remarketing tag. + Required. + origin_id (str): + Origin ID which can be any sequence of + letters and digits. The ID sequence (destination + ID + origin ID) must be unique. + title (str): + Required. Title, for example, Book your train + ticket. Required. + destination_name (str): + Destination name, for example, Paris. + destination_address (str): + Destination address which can be specified in + one of the following formats. (1) City, state, + code, country, for example, Mountain View, CA, + USA. (2) Full address, for example, 123 + Boulevard St, Mountain View, CA 94043. (3) + Latitude-longitude in the DDD format, for + example, 41.40338, 2.17403. + origin_name (str): + Origin name, for example, London. + price (str): + Price which can be a number followed by the + alphabetic currency code, ISO 4217 standard. Use + '.' as the decimal mark, for example, 100.00 + USD. + sale_price (str): + Sale price which can be a number followed by + the alphabetic currency code, ISO 4217 standard. + Use '.' as the decimal mark, for example, 80.00 + USD. Must be less than the 'price' field. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $100.00. + formatted_sale_price (str): + Formatted sale price which can be any + characters. If set, this attribute will be used + instead of 'sale price', for example, On sale + for $80.00. + category (str): + Category, for example, Express. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Paris + trains. + similar_destination_ids (Sequence[str]): + Similar destination IDs, for example, NYC. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + """ + + destination_id = proto.Field(proto.STRING, number=1,) + origin_id = proto.Field(proto.STRING, number=2,) + title = proto.Field(proto.STRING, number=3,) + destination_name = proto.Field(proto.STRING, number=4,) + destination_address = proto.Field(proto.STRING, number=5,) + origin_name = proto.Field(proto.STRING, number=6,) + price = proto.Field(proto.STRING, number=7,) + sale_price = proto.Field(proto.STRING, number=8,) + formatted_price = proto.Field(proto.STRING, number=9,) + formatted_sale_price = proto.Field(proto.STRING, number=10,) + category = proto.Field(proto.STRING, number=11,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=12,) + similar_destination_ids = proto.RepeatedField(proto.STRING, number=13,) + image_url = proto.Field(proto.STRING, number=14,) + android_app_link = proto.Field(proto.STRING, number=15,) + ios_app_link = proto.Field(proto.STRING, number=16,) + ios_app_store_id = proto.Field(proto.INT64, number=17,) + + +class DynamicLocalAsset(proto.Message): + r"""A dynamic local asset. + + Attributes: + deal_id (str): + Required. Deal ID which can be any sequence + of letters and digits, and must be unique and + match the values of remarketing tag. Required. + deal_name (str): + Required. Deal name, for example, 50% off at + Mountain View Grocers. Required. + subtitle (str): + Subtitle, for example, Groceries. + description (str): + Description, for example, Save on your weekly + bill. + price (str): + Price which can be a number followed by the + alphabetic currency code, ISO 4217 standard. Use + '.' as the decimal mark, for example, 100.00 + USD. + sale_price (str): + Sale price which can be number followed by + the alphabetic currency code, ISO 4217 standard. + Use '.' as the decimal mark, for example, 80.00 + USD. Must be less than the 'price' field. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + address (str): + Address which can be specified in one of the + following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403. + category (str): + Category, for example, Food. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Save + groceries coupons. + formatted_price (str): + Formatted price which can be any characters. + If set, this attribute will be used instead of + 'price', for example, Starting at $100.00. + formatted_sale_price (str): + Formatted sale price which can be any + characters. If set, this attribute will be used + instead of 'sale price', for example, On sale + for $80.00. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + similar_deal_ids (Sequence[str]): + Similar deal IDs, for example, 1275. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + """ + + deal_id = proto.Field(proto.STRING, number=1,) + deal_name = proto.Field(proto.STRING, number=2,) + subtitle = proto.Field(proto.STRING, number=3,) + description = proto.Field(proto.STRING, number=4,) + price = proto.Field(proto.STRING, number=5,) + sale_price = proto.Field(proto.STRING, number=6,) + image_url = proto.Field(proto.STRING, number=7,) + address = proto.Field(proto.STRING, number=8,) + category = proto.Field(proto.STRING, number=9,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=10,) + formatted_price = proto.Field(proto.STRING, number=11,) + formatted_sale_price = proto.Field(proto.STRING, number=12,) + android_app_link = proto.Field(proto.STRING, number=13,) + similar_deal_ids = proto.RepeatedField(proto.STRING, number=14,) + ios_app_link = proto.Field(proto.STRING, number=15,) + ios_app_store_id = proto.Field(proto.INT64, number=16,) + + +class DynamicJobsAsset(proto.Message): + r"""A dynamic jobs asset. + + Attributes: + job_id (str): + Required. Job ID which can be any sequence of + letters and digits, and must be unique and match + the values of remarketing tag. Required. + location_id (str): + Location ID which can be any sequence of + letters and digits. The ID sequence (job ID + + location ID) must be unique. + job_title (str): + Required. Job title, for example, Software + engineer. Required. + job_subtitle (str): + Job subtitle, for example, Level II. + description (str): + Description, for example, Apply your + technical skills. + image_url (str): + Image URL, for example, + http://www.example.com/image.png. The image will + not be uploaded as image asset. + job_category (str): + Job category, for example, Technical. + contextual_keywords (Sequence[str]): + Contextual keywords, for example, Software + engineering job. + address (str): + Address which can be specified in one of the + following formats. (1) City, state, code, + country, for example, Mountain View, CA, USA. + (2) Full address, for example, 123 Boulevard St, + Mountain View, CA 94043. (3) Latitude-longitude + in the DDD format, for example, 41.40338, + 2.17403. + salary (str): + Salary, for example, $100,000. + android_app_link (str): + Android deep link, for example, + android-app://com.example.android/http/example.com/gizmos?1234. + similar_job_ids (Sequence[str]): + Similar job IDs, for example, 1275. + ios_app_link (str): + iOS deep link, for example, + exampleApp://content/page. + ios_app_store_id (int): + iOS app store ID. This is used to check if the user has the + app installed on their device before deep linking. If this + field is set, then the ios_app_link field must also be + present. + """ + + job_id = proto.Field(proto.STRING, number=1,) + location_id = proto.Field(proto.STRING, number=2,) + job_title = proto.Field(proto.STRING, number=3,) + job_subtitle = proto.Field(proto.STRING, number=4,) + description = proto.Field(proto.STRING, number=5,) + image_url = proto.Field(proto.STRING, number=6,) + job_category = proto.Field(proto.STRING, number=7,) + contextual_keywords = proto.RepeatedField(proto.STRING, number=8,) + address = proto.Field(proto.STRING, number=9,) + salary = proto.Field(proto.STRING, number=10,) + android_app_link = proto.Field(proto.STRING, number=11,) + similar_job_ids = proto.RepeatedField(proto.STRING, number=12,) + ios_app_link = proto.Field(proto.STRING, number=13,) + ios_app_store_id = proto.Field(proto.INT64, number=14,) + + +class LocationAsset(proto.Message): + r"""A location asset. + + Attributes: + place_id (str): + Place IDs uniquely identify a place in the + Google Places database and on Google Maps. + This field is unique for a given customer ID and + asset type. See + https://developers.google.com/places/web-service/place-id + to learn more about Place ID. + business_profile_locations (Sequence[google.ads.googleads.v12.common.types.BusinessProfileLocation]): + The list of business locations for the + customer. This will only be returned if the + Location Asset is syncing from the Business + Profile account. It is possible to have multiple + Business Profile listings under the same account + that point to the same Place ID. + location_ownership_type (google.ads.googleads.v12.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): + The type of location ownership. If the type is + BUSINESS_OWNER, it will be served as a location extension. + If the type is AFFILIATE, it will be served as an affiliate + location. + """ + + place_id = proto.Field(proto.STRING, number=1,) + business_profile_locations = proto.RepeatedField( + proto.MESSAGE, number=2, message="BusinessProfileLocation", + ) + location_ownership_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_location_ownership_type.LocationOwnershipTypeEnum.LocationOwnershipType, + ) + + +class BusinessProfileLocation(proto.Message): + r"""Business Profile location data synced from the linked + Business Profile account. + + Attributes: + labels (Sequence[str]): + Advertiser specified label for the location + on the Business Profile account. This is synced + from the Business Profile account. + store_code (str): + Business Profile store code of this location. + This is synced from the Business Profile + account. + listing_id (int): + Listing ID of this Business Profile location. + This is synced from the linked Business Profile + account. + """ + + labels = proto.RepeatedField(proto.STRING, number=1,) + store_code = proto.Field(proto.STRING, number=2,) + listing_id = proto.Field(proto.INT64, number=3,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/asset_usage.py b/google/ads/googleads/v12/common/types/asset_usage.py new file mode 100644 index 000000000..7f081298c --- /dev/null +++ b/google/ads/googleads/v12/common/types/asset_usage.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + served_asset_field_type as gage_served_asset_field_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"AssetUsage",}, +) + + +class AssetUsage(proto.Message): + r"""Contains the usage information of the asset. + + Attributes: + asset (str): + Resource name of the asset. + served_asset_field_type (google.ads.googleads.v12.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + The served field type of the asset. + """ + + asset = proto.Field(proto.STRING, number=1,) + served_asset_field_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_served_asset_field_type.ServedAssetFieldTypeEnum.ServedAssetFieldType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/audiences.py b/google/ads/googleads/v12/common/types/audiences.py new file mode 100644 index 000000000..1e55b3b37 --- /dev/null +++ b/google/ads/googleads/v12/common/types/audiences.py @@ -0,0 +1,378 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import gender_type +from google.ads.googleads.v12.enums.types import income_range_type +from google.ads.googleads.v12.enums.types import parental_status_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "AudienceDimension", + "AudienceExclusionDimension", + "ExclusionSegment", + "AgeDimension", + "AgeSegment", + "GenderDimension", + "HouseholdIncomeDimension", + "ParentalStatusDimension", + "AudienceSegmentDimension", + "AudienceSegment", + "UserListSegment", + "UserInterestSegment", + "LifeEventSegment", + "DetailedDemographicSegment", + "CustomAudienceSegment", + }, +) + + +class AudienceDimension(proto.Message): + r"""Positive dimension specifying user's audience. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + age (google.ads.googleads.v12.common.types.AgeDimension): + Dimension specifying users by their age. + + This field is a member of `oneof`_ ``dimension``. + gender (google.ads.googleads.v12.common.types.GenderDimension): + Dimension specifying users by their gender. + + This field is a member of `oneof`_ ``dimension``. + household_income (google.ads.googleads.v12.common.types.HouseholdIncomeDimension): + Dimension specifying users by their household + income. + + This field is a member of `oneof`_ ``dimension``. + parental_status (google.ads.googleads.v12.common.types.ParentalStatusDimension): + Dimension specifying users by their parental + status. + + This field is a member of `oneof`_ ``dimension``. + audience_segments (google.ads.googleads.v12.common.types.AudienceSegmentDimension): + Dimension specifying users by their + membership in other audience segments. + + This field is a member of `oneof`_ ``dimension``. + """ + + age = proto.Field( + proto.MESSAGE, number=1, oneof="dimension", message="AgeDimension", + ) + gender = proto.Field( + proto.MESSAGE, number=2, oneof="dimension", message="GenderDimension", + ) + household_income = proto.Field( + proto.MESSAGE, + number=3, + oneof="dimension", + message="HouseholdIncomeDimension", + ) + parental_status = proto.Field( + proto.MESSAGE, + number=4, + oneof="dimension", + message="ParentalStatusDimension", + ) + audience_segments = proto.Field( + proto.MESSAGE, + number=5, + oneof="dimension", + message="AudienceSegmentDimension", + ) + + +class AudienceExclusionDimension(proto.Message): + r"""Negative dimension specifying users to exclude from the + audience. + + Attributes: + exclusions (Sequence[google.ads.googleads.v12.common.types.ExclusionSegment]): + Audience segment to be excluded. + """ + + exclusions = proto.RepeatedField( + proto.MESSAGE, number=1, message="ExclusionSegment", + ) + + +class ExclusionSegment(proto.Message): + r"""An audience segment to be excluded from an audience. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + user_list (google.ads.googleads.v12.common.types.UserListSegment): + User list segment to be excluded. + + This field is a member of `oneof`_ ``segment``. + """ + + user_list = proto.Field( + proto.MESSAGE, number=1, oneof="segment", message="UserListSegment", + ) + + +class AgeDimension(proto.Message): + r"""Dimension specifying users by their age. + + Attributes: + age_ranges (Sequence[google.ads.googleads.v12.common.types.AgeSegment]): + Contiguous age range to be included in the + dimension. + include_undetermined (bool): + Include users whose age is not determined. + + This field is a member of `oneof`_ ``_include_undetermined``. + """ + + age_ranges = proto.RepeatedField( + proto.MESSAGE, number=1, message="AgeSegment", + ) + include_undetermined = proto.Field(proto.BOOL, number=2, optional=True,) + + +class AgeSegment(proto.Message): + r"""Contiguous age range. + + Attributes: + min_age (int): + Minimum age to include. A minimum age must be + specified and must be at least 18. Allowed + values are 18, 25, 35, 45, 55, and 65. + + This field is a member of `oneof`_ ``_min_age``. + max_age (int): + Maximum age to include. A maximum age need not be specified. + If specified, max_age must be greater than min_age, and + allowed values are 24, 34, 44, 54, and 64. + + This field is a member of `oneof`_ ``_max_age``. + """ + + min_age = proto.Field(proto.INT32, number=1, optional=True,) + max_age = proto.Field(proto.INT32, number=2, optional=True,) + + +class GenderDimension(proto.Message): + r"""Dimension specifying users by their gender. + + Attributes: + genders (Sequence[google.ads.googleads.v12.enums.types.GenderTypeEnum.GenderType]): + Included gender demographic segments. + include_undetermined (bool): + Include users whose gender is not determined. + + This field is a member of `oneof`_ ``_include_undetermined``. + """ + + genders = proto.RepeatedField( + proto.ENUM, number=1, enum=gender_type.GenderTypeEnum.GenderType, + ) + include_undetermined = proto.Field(proto.BOOL, number=2, optional=True,) + + +class HouseholdIncomeDimension(proto.Message): + r"""Dimension specifying users by their household income. + + Attributes: + income_ranges (Sequence[google.ads.googleads.v12.enums.types.IncomeRangeTypeEnum.IncomeRangeType]): + Included household income demographic + segments. + include_undetermined (bool): + Include users whose household income is not + determined. + + This field is a member of `oneof`_ ``_include_undetermined``. + """ + + income_ranges = proto.RepeatedField( + proto.ENUM, + number=1, + enum=income_range_type.IncomeRangeTypeEnum.IncomeRangeType, + ) + include_undetermined = proto.Field(proto.BOOL, number=2, optional=True,) + + +class ParentalStatusDimension(proto.Message): + r"""Dimension specifying users by their parental status. + + Attributes: + parental_statuses (Sequence[google.ads.googleads.v12.enums.types.ParentalStatusTypeEnum.ParentalStatusType]): + Included parental status demographic + segments. + include_undetermined (bool): + Include users whose parental status is + undetermined. + + This field is a member of `oneof`_ ``_include_undetermined``. + """ + + parental_statuses = proto.RepeatedField( + proto.ENUM, + number=1, + enum=parental_status_type.ParentalStatusTypeEnum.ParentalStatusType, + ) + include_undetermined = proto.Field(proto.BOOL, number=2, optional=True,) + + +class AudienceSegmentDimension(proto.Message): + r"""Dimension specifying users by their membership in other + audience segments. + + Attributes: + segments (Sequence[google.ads.googleads.v12.common.types.AudienceSegment]): + Included audience segments. Users are + included if they belong to at least one segment. + """ + + segments = proto.RepeatedField( + proto.MESSAGE, number=1, message="AudienceSegment", + ) + + +class AudienceSegment(proto.Message): + r"""Positive audience segment. + + 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: + user_list (google.ads.googleads.v12.common.types.UserListSegment): + User list segment. + + This field is a member of `oneof`_ ``segment``. + user_interest (google.ads.googleads.v12.common.types.UserInterestSegment): + Affinity or In-market segment. + + This field is a member of `oneof`_ ``segment``. + life_event (google.ads.googleads.v12.common.types.LifeEventSegment): + Live-event audience segment. + + This field is a member of `oneof`_ ``segment``. + detailed_demographic (google.ads.googleads.v12.common.types.DetailedDemographicSegment): + Detailed demographic segment. + + This field is a member of `oneof`_ ``segment``. + custom_audience (google.ads.googleads.v12.common.types.CustomAudienceSegment): + Custom audience segment. + + This field is a member of `oneof`_ ``segment``. + """ + + user_list = proto.Field( + proto.MESSAGE, number=1, oneof="segment", message="UserListSegment", + ) + user_interest = proto.Field( + proto.MESSAGE, number=2, oneof="segment", message="UserInterestSegment", + ) + life_event = proto.Field( + proto.MESSAGE, number=3, oneof="segment", message="LifeEventSegment", + ) + detailed_demographic = proto.Field( + proto.MESSAGE, + number=4, + oneof="segment", + message="DetailedDemographicSegment", + ) + custom_audience = proto.Field( + proto.MESSAGE, + number=5, + oneof="segment", + message="CustomAudienceSegment", + ) + + +class UserListSegment(proto.Message): + r"""User list segment. + + Attributes: + user_list (str): + The user list resource. + + This field is a member of `oneof`_ ``_user_list``. + """ + + user_list = proto.Field(proto.STRING, number=1, optional=True,) + + +class UserInterestSegment(proto.Message): + r"""User interest segment. + + Attributes: + user_interest_category (str): + The user interest resource. + + This field is a member of `oneof`_ ``_user_interest_category``. + """ + + user_interest_category = proto.Field(proto.STRING, number=1, optional=True,) + + +class LifeEventSegment(proto.Message): + r"""Live event segment. + + Attributes: + life_event (str): + The life event resource. + + This field is a member of `oneof`_ ``_life_event``. + """ + + life_event = proto.Field(proto.STRING, number=1, optional=True,) + + +class DetailedDemographicSegment(proto.Message): + r"""Detailed demographic segment. + + Attributes: + detailed_demographic (str): + The detailed demographic resource. + + This field is a member of `oneof`_ ``_detailed_demographic``. + """ + + detailed_demographic = proto.Field(proto.STRING, number=1, optional=True,) + + +class CustomAudienceSegment(proto.Message): + r"""Custom audience segment. + + Attributes: + custom_audience (str): + The custom audience resource. + + This field is a member of `oneof`_ ``_custom_audience``. + """ + + custom_audience = proto.Field(proto.STRING, number=1, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/bidding.py b/google/ads/googleads/v12/common/types/bidding.py new file mode 100644 index 000000000..9f350d052 --- /dev/null +++ b/google/ads/googleads/v12/common/types/bidding.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + target_impression_share_location, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "Commission", + "EnhancedCpc", + "ManualCpa", + "ManualCpc", + "ManualCpm", + "ManualCpv", + "MaximizeConversions", + "MaximizeConversionValue", + "TargetCpa", + "TargetCpm", + "TargetImpressionShare", + "TargetRoas", + "TargetSpend", + "PercentCpc", + }, +) + + +class Commission(proto.Message): + r"""Commission is an automatic bidding strategy in which the + advertiser pays a certain portion of the conversion value. + + Attributes: + commission_rate_micros (int): + Commission rate defines the portion of the conversion value + that the advertiser will be billed. A commission rate of x + should be passed into this field as (x \* 1,000,000). For + example, 106,000 represents a commission rate of 0.106 + (10.6%). + + This field is a member of `oneof`_ ``_commission_rate_micros``. + """ + + commission_rate_micros = proto.Field(proto.INT64, number=2, optional=True,) + + +class EnhancedCpc(proto.Message): + r"""An automated bidding strategy that raises bids for clicks that seem + more likely to lead to a conversion and lowers them for clicks where + they seem less likely. + + This bidding strategy is deprecated and cannot be created anymore. + Use ManualCpc with enhanced_cpc_enabled set to true for equivalent + functionality. + + """ + + +class ManualCpa(proto.Message): + r"""Manual bidding strategy that allows advertiser to set the bid + per advertiser-specified action. + + """ + + +class ManualCpc(proto.Message): + r"""Manual click-based bidding where user pays per click. + + Attributes: + enhanced_cpc_enabled (bool): + Whether bids are to be enhanced based on + conversion optimizer data. + + This field is a member of `oneof`_ ``_enhanced_cpc_enabled``. + """ + + enhanced_cpc_enabled = proto.Field(proto.BOOL, number=2, optional=True,) + + +class ManualCpm(proto.Message): + r"""Manual impression-based bidding where user pays per thousand + impressions. + + """ + + +class ManualCpv(proto.Message): + r"""View based bidding where user pays per video view. + """ + + +class MaximizeConversions(proto.Message): + r"""An automated bidding strategy to help get the most + conversions for your campaigns while spending your budget. + + Attributes: + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. Mutable for portfolio + bidding strategies only. + cpc_bid_floor_micros (int): + Minimum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. Mutable for portfolio + bidding strategies only. + target_cpa_micros (int): + The target cost-per-action (CPA) option. This + is the average amount that you would like to + spend per conversion action specified in micro + units of the bidding strategy's currency. If + set, the bid strategy will get as many + conversions as possible at or below the target + cost-per-action. If the target CPA is not set, + the bid strategy will aim to achieve the lowest + possible CPA given the budget. + """ + + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=2,) + cpc_bid_floor_micros = proto.Field(proto.INT64, number=3,) + target_cpa_micros = proto.Field(proto.INT64, number=4,) + + +class MaximizeConversionValue(proto.Message): + r"""An automated bidding strategy to help get the most conversion + value for your campaigns while spending your budget. + + Attributes: + target_roas (float): + The target return on ad spend (ROAS) option. + If set, the bid strategy will maximize revenue + while averaging the target return on ad spend. + If the target ROAS is high, the bid strategy may + not be able to spend the full budget. If the + target ROAS is not set, the bid strategy will + aim to achieve the highest possible ROAS for the + budget. + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. Mutable for portfolio + bidding strategies only. + cpc_bid_floor_micros (int): + Minimum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. Mutable for portfolio + bidding strategies only. + """ + + target_roas = proto.Field(proto.DOUBLE, number=2,) + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=3,) + cpc_bid_floor_micros = proto.Field(proto.INT64, number=4,) + + +class TargetCpa(proto.Message): + r"""An automated bid strategy that sets bids to help get as many + conversions as possible at the target cost-per-acquisition (CPA) + you set. + + Attributes: + target_cpa_micros (int): + Average CPA target. + This target should be greater than or equal to + minimum billable unit based on the currency for + the account. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. This should only be set + for portfolio bid strategies. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + cpc_bid_floor_micros (int): + Minimum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. This should only be set + for portfolio bid strategies. + + This field is a member of `oneof`_ ``_cpc_bid_floor_micros``. + """ + + target_cpa_micros = proto.Field(proto.INT64, number=4, optional=True,) + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=5, optional=True,) + cpc_bid_floor_micros = proto.Field(proto.INT64, number=6, optional=True,) + + +class TargetCpm(proto.Message): + r"""Target CPM (cost per thousand impressions) is an automated + bidding strategy that sets bids to optimize performance given + the target CPM you set. + + """ + + +class TargetImpressionShare(proto.Message): + r"""An automated bidding strategy that sets bids so that a + certain percentage of search ads are shown at the top of the + first page (or other targeted location). + + Attributes: + location (google.ads.googleads.v12.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): + The targeted location on the search results + page. + location_fraction_micros (int): + The chosen fraction of ads to be shown in the + targeted location in micros. For example, 1% + equals 10,000. + + This field is a member of `oneof`_ ``_location_fraction_micros``. + cpc_bid_ceiling_micros (int): + The highest CPC bid the automated bidding + system is permitted to specify. This is a + required field entered by the advertiser that + sets the ceiling and specified in local micros. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + """ + + location = proto.Field( + proto.ENUM, + number=1, + enum=target_impression_share_location.TargetImpressionShareLocationEnum.TargetImpressionShareLocation, + ) + location_fraction_micros = proto.Field( + proto.INT64, number=4, optional=True, + ) + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=5, optional=True,) + + +class TargetRoas(proto.Message): + r"""An automated bidding strategy that helps you maximize revenue + while averaging a specific target return on ad spend (ROAS). + + Attributes: + target_roas (float): + Required. The chosen revenue (based on + conversion data) per unit of spend. Value must + be between 0.01 and 1000.0, inclusive. + + This field is a member of `oneof`_ ``_target_roas``. + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. This should only be set + for portfolio bid strategies. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + cpc_bid_floor_micros (int): + Minimum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. This should only be set + for portfolio bid strategies. + + This field is a member of `oneof`_ ``_cpc_bid_floor_micros``. + """ + + target_roas = proto.Field(proto.DOUBLE, number=4, optional=True,) + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=5, optional=True,) + cpc_bid_floor_micros = proto.Field(proto.INT64, number=6, optional=True,) + + +class TargetSpend(proto.Message): + r"""An automated bid strategy that sets your bids to help get as + many clicks as possible within your budget. + + Attributes: + target_spend_micros (int): + The spend target under which to maximize + clicks. A TargetSpend bidder will attempt to + spend the smaller of this value or the natural + throttling spend amount. + If not specified, the budget is used as the + spend target. This field is deprecated and + should no longer be used. See + https://ads-developers.googleblog.com/2020/05/reminder-about-sunset-creation-of.html + for details. + + This field is a member of `oneof`_ ``_target_spend_micros``. + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid + strategy. The limit applies to all keywords + managed by the strategy. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + """ + + target_spend_micros = proto.Field(proto.INT64, number=3, optional=True,) + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=4, optional=True,) + + +class PercentCpc(proto.Message): + r"""A bidding strategy where bids are a fraction of the + advertised price for some good or service. + + Attributes: + cpc_bid_ceiling_micros (int): + Maximum bid limit that can be set by the bid strategy. This + is an optional field entered by the advertiser and specified + in local micros. Note: A zero value is interpreted in the + same way as having bid_ceiling undefined. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + enhanced_cpc_enabled (bool): + Adjusts the bid for each auction upward or downward, + depending on the likelihood of a conversion. Individual bids + may exceed cpc_bid_ceiling_micros, but the average bid + amount for a campaign should not. + + This field is a member of `oneof`_ ``_enhanced_cpc_enabled``. + """ + + cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=3, optional=True,) + enhanced_cpc_enabled = proto.Field(proto.BOOL, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/click_location.py b/google/ads/googleads/v12/common/types/click_location.py new file mode 100644 index 000000000..c41e35b72 --- /dev/null +++ b/google/ads/googleads/v12/common/types/click_location.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"ClickLocation",}, +) + + +class ClickLocation(proto.Message): + r"""Location criteria associated with a click. + + Attributes: + city (str): + The city location criterion associated with + the impression. + + This field is a member of `oneof`_ ``_city``. + country (str): + The country location criterion associated + with the impression. + + This field is a member of `oneof`_ ``_country``. + metro (str): + The metro location criterion associated with + the impression. + + This field is a member of `oneof`_ ``_metro``. + most_specific (str): + The most specific location criterion + associated with the impression. + + This field is a member of `oneof`_ ``_most_specific``. + region (str): + The region location criterion associated with + the impression. + + This field is a member of `oneof`_ ``_region``. + """ + + city = proto.Field(proto.STRING, number=6, optional=True,) + country = proto.Field(proto.STRING, number=7, optional=True,) + metro = proto.Field(proto.STRING, number=8, optional=True,) + most_specific = proto.Field(proto.STRING, number=9, optional=True,) + region = proto.Field(proto.STRING, number=10, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/criteria.py b/google/ads/googleads/v12/common/types/criteria.py new file mode 100644 index 000000000..67ca07d53 --- /dev/null +++ b/google/ads/googleads/v12/common/types/criteria.py @@ -0,0 +1,1477 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import age_range_type +from google.ads.googleads.v12.enums.types import app_payment_model_type +from google.ads.googleads.v12.enums.types import content_label_type +from google.ads.googleads.v12.enums.types import day_of_week as gage_day_of_week +from google.ads.googleads.v12.enums.types import device +from google.ads.googleads.v12.enums.types import gender_type +from google.ads.googleads.v12.enums.types import hotel_date_selection_type +from google.ads.googleads.v12.enums.types import income_range_type +from google.ads.googleads.v12.enums.types import interaction_type +from google.ads.googleads.v12.enums.types import keyword_match_type +from google.ads.googleads.v12.enums.types import listing_group_type +from google.ads.googleads.v12.enums.types import location_group_radius_units +from google.ads.googleads.v12.enums.types import minute_of_hour +from google.ads.googleads.v12.enums.types import parental_status_type +from google.ads.googleads.v12.enums.types import preferred_content_type +from google.ads.googleads.v12.enums.types import product_bidding_category_level +from google.ads.googleads.v12.enums.types import ( + product_channel as gage_product_channel, +) +from google.ads.googleads.v12.enums.types import ( + product_channel_exclusivity as gage_product_channel_exclusivity, +) +from google.ads.googleads.v12.enums.types import ( + product_condition as gage_product_condition, +) +from google.ads.googleads.v12.enums.types import product_custom_attribute_index +from google.ads.googleads.v12.enums.types import product_type_level +from google.ads.googleads.v12.enums.types import proximity_radius_units +from google.ads.googleads.v12.enums.types import webpage_condition_operand +from google.ads.googleads.v12.enums.types import webpage_condition_operator + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "KeywordInfo", + "PlacementInfo", + "MobileAppCategoryInfo", + "MobileApplicationInfo", + "LocationInfo", + "DeviceInfo", + "PreferredContentInfo", + "ListingGroupInfo", + "ListingScopeInfo", + "ListingDimensionInfo", + "HotelIdInfo", + "HotelClassInfo", + "HotelCountryRegionInfo", + "HotelStateInfo", + "HotelCityInfo", + "ProductBiddingCategoryInfo", + "ProductBrandInfo", + "ProductChannelInfo", + "ProductChannelExclusivityInfo", + "ProductConditionInfo", + "ProductCustomAttributeInfo", + "ProductItemIdInfo", + "ProductTypeInfo", + "ProductGroupingInfo", + "ProductLabelsInfo", + "ProductLegacyConditionInfo", + "ProductTypeFullInfo", + "UnknownListingDimensionInfo", + "HotelDateSelectionTypeInfo", + "HotelAdvanceBookingWindowInfo", + "HotelLengthOfStayInfo", + "HotelCheckInDateRangeInfo", + "HotelCheckInDayInfo", + "InteractionTypeInfo", + "AdScheduleInfo", + "AgeRangeInfo", + "GenderInfo", + "IncomeRangeInfo", + "ParentalStatusInfo", + "YouTubeVideoInfo", + "YouTubeChannelInfo", + "UserListInfo", + "ProximityInfo", + "GeoPointInfo", + "AddressInfo", + "TopicInfo", + "LanguageInfo", + "IpBlockInfo", + "ContentLabelInfo", + "CarrierInfo", + "UserInterestInfo", + "WebpageInfo", + "WebpageConditionInfo", + "WebpageSampleInfo", + "OperatingSystemVersionInfo", + "AppPaymentModelInfo", + "MobileDeviceInfo", + "CustomAffinityInfo", + "CustomIntentInfo", + "LocationGroupInfo", + "CustomAudienceInfo", + "CombinedAudienceInfo", + "AudienceInfo", + "KeywordThemeInfo", + }, +) + + +class KeywordInfo(proto.Message): + r"""A keyword criterion. + + Attributes: + text (str): + The text of the keyword (at most 80 + characters and 10 words). + + This field is a member of `oneof`_ ``_text``. + match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + The match type of the keyword. + """ + + text = proto.Field(proto.STRING, number=3, optional=True,) + match_type = proto.Field( + proto.ENUM, + number=2, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + + +class PlacementInfo(proto.Message): + r"""A placement criterion. This can be used to modify bids for + sites when targeting the content network. + + Attributes: + url (str): + URL of the placement. + For example, "http://www.domain.com". + + This field is a member of `oneof`_ ``_url``. + """ + + url = proto.Field(proto.STRING, number=2, optional=True,) + + +class MobileAppCategoryInfo(proto.Message): + r"""A mobile app category criterion. + + Attributes: + mobile_app_category_constant (str): + The mobile app category constant resource + name. + + This field is a member of `oneof`_ ``_mobile_app_category_constant``. + """ + + mobile_app_category_constant = proto.Field( + proto.STRING, number=2, optional=True, + ) + + +class MobileApplicationInfo(proto.Message): + r"""A mobile application criterion. + + Attributes: + app_id (str): + A string that uniquely identifies a mobile application to + Google Ads API. The format of this string is + "{platform}-{platform_native_id}", where platform is "1" for + iOS apps and "2" for Android apps, and where + platform_native_id is the mobile application identifier + native to the corresponding platform. For iOS, this native + identifier is the 9 digit string that appears at the end of + an App Store URL (for example, "476943146" for "Flood-It! 2" + whose App Store link is + "http://itunes.apple.com/us/app/flood-it!-2/id476943146"). + For Android, this native identifier is the application's + package name (for example, "com.labpixies.colordrips" for + "Color Drips" given Google Play link + "https://play.google.com/store/apps/details?id=com.labpixies.colordrips"). + A well formed app id for Google Ads API would thus be + "1-476943146" for iOS and "2-com.labpixies.colordrips" for + Android. This field is required and must be set in CREATE + operations. + + This field is a member of `oneof`_ ``_app_id``. + name (str): + Name of this mobile application. + + This field is a member of `oneof`_ ``_name``. + """ + + app_id = proto.Field(proto.STRING, number=4, optional=True,) + name = proto.Field(proto.STRING, number=5, optional=True,) + + +class LocationInfo(proto.Message): + r"""A location criterion. + + Attributes: + geo_target_constant (str): + The geo target constant resource name. + + This field is a member of `oneof`_ ``_geo_target_constant``. + """ + + geo_target_constant = proto.Field(proto.STRING, number=2, optional=True,) + + +class DeviceInfo(proto.Message): + r"""A device criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.DeviceEnum.Device): + Type of the device. + """ + + type_ = proto.Field(proto.ENUM, number=1, enum=device.DeviceEnum.Device,) + + +class PreferredContentInfo(proto.Message): + r"""A preferred content criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.PreferredContentTypeEnum.PreferredContentType): + Type of the preferred content. + """ + + type_ = proto.Field( + proto.ENUM, + number=2, + enum=preferred_content_type.PreferredContentTypeEnum.PreferredContentType, + ) + + +class ListingGroupInfo(proto.Message): + r"""A listing group criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.ListingGroupTypeEnum.ListingGroupType): + Type of the listing group. + case_value (google.ads.googleads.v12.common.types.ListingDimensionInfo): + Dimension value with which this listing group + is refining its parent. Undefined for the root + group. + parent_ad_group_criterion (str): + Resource name of ad group criterion which is + the parent listing group subdivision. Null for + the root group. + + This field is a member of `oneof`_ ``_parent_ad_group_criterion``. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=listing_group_type.ListingGroupTypeEnum.ListingGroupType, + ) + case_value = proto.Field( + proto.MESSAGE, number=2, message="ListingDimensionInfo", + ) + parent_ad_group_criterion = proto.Field( + proto.STRING, number=4, optional=True, + ) + + +class ListingScopeInfo(proto.Message): + r"""A listing scope criterion. + + Attributes: + dimensions (Sequence[google.ads.googleads.v12.common.types.ListingDimensionInfo]): + Scope of the campaign criterion. + """ + + dimensions = proto.RepeatedField( + proto.MESSAGE, number=2, message="ListingDimensionInfo", + ) + + +class ListingDimensionInfo(proto.Message): + r"""Listing dimensions for listing group criterion. + + 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: + hotel_id (google.ads.googleads.v12.common.types.HotelIdInfo): + Advertiser-specific hotel ID. + + This field is a member of `oneof`_ ``dimension``. + hotel_class (google.ads.googleads.v12.common.types.HotelClassInfo): + Class of the hotel as a number of stars 1 to + 5. + + This field is a member of `oneof`_ ``dimension``. + hotel_country_region (google.ads.googleads.v12.common.types.HotelCountryRegionInfo): + Country or Region the hotel is located in. + + This field is a member of `oneof`_ ``dimension``. + hotel_state (google.ads.googleads.v12.common.types.HotelStateInfo): + State the hotel is located in. + + This field is a member of `oneof`_ ``dimension``. + hotel_city (google.ads.googleads.v12.common.types.HotelCityInfo): + City the hotel is located in. + + This field is a member of `oneof`_ ``dimension``. + product_bidding_category (google.ads.googleads.v12.common.types.ProductBiddingCategoryInfo): + Bidding category of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_brand (google.ads.googleads.v12.common.types.ProductBrandInfo): + Brand of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_channel (google.ads.googleads.v12.common.types.ProductChannelInfo): + Locality of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_channel_exclusivity (google.ads.googleads.v12.common.types.ProductChannelExclusivityInfo): + Availability of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_condition (google.ads.googleads.v12.common.types.ProductConditionInfo): + Condition of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_custom_attribute (google.ads.googleads.v12.common.types.ProductCustomAttributeInfo): + Custom attribute of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_item_id (google.ads.googleads.v12.common.types.ProductItemIdInfo): + Item id of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_type (google.ads.googleads.v12.common.types.ProductTypeInfo): + Type of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_grouping (google.ads.googleads.v12.common.types.ProductGroupingInfo): + Grouping of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_labels (google.ads.googleads.v12.common.types.ProductLabelsInfo): + Labels of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_legacy_condition (google.ads.googleads.v12.common.types.ProductLegacyConditionInfo): + Legacy condition of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_type_full (google.ads.googleads.v12.common.types.ProductTypeFullInfo): + Full type of a product offer. + + This field is a member of `oneof`_ ``dimension``. + unknown_listing_dimension (google.ads.googleads.v12.common.types.UnknownListingDimensionInfo): + Unknown dimension. Set when no other listing + dimension is set. + + This field is a member of `oneof`_ ``dimension``. + """ + + hotel_id = proto.Field( + proto.MESSAGE, number=2, oneof="dimension", message="HotelIdInfo", + ) + hotel_class = proto.Field( + proto.MESSAGE, number=3, oneof="dimension", message="HotelClassInfo", + ) + hotel_country_region = proto.Field( + proto.MESSAGE, + number=4, + oneof="dimension", + message="HotelCountryRegionInfo", + ) + hotel_state = proto.Field( + proto.MESSAGE, number=5, oneof="dimension", message="HotelStateInfo", + ) + hotel_city = proto.Field( + proto.MESSAGE, number=6, oneof="dimension", message="HotelCityInfo", + ) + product_bidding_category = proto.Field( + proto.MESSAGE, + number=13, + oneof="dimension", + message="ProductBiddingCategoryInfo", + ) + product_brand = proto.Field( + proto.MESSAGE, number=15, oneof="dimension", message="ProductBrandInfo", + ) + product_channel = proto.Field( + proto.MESSAGE, + number=8, + oneof="dimension", + message="ProductChannelInfo", + ) + product_channel_exclusivity = proto.Field( + proto.MESSAGE, + number=9, + oneof="dimension", + message="ProductChannelExclusivityInfo", + ) + product_condition = proto.Field( + proto.MESSAGE, + number=10, + oneof="dimension", + message="ProductConditionInfo", + ) + product_custom_attribute = proto.Field( + proto.MESSAGE, + number=16, + oneof="dimension", + message="ProductCustomAttributeInfo", + ) + product_item_id = proto.Field( + proto.MESSAGE, + number=11, + oneof="dimension", + message="ProductItemIdInfo", + ) + product_type = proto.Field( + proto.MESSAGE, number=12, oneof="dimension", message="ProductTypeInfo", + ) + product_grouping = proto.Field( + proto.MESSAGE, + number=17, + oneof="dimension", + message="ProductGroupingInfo", + ) + product_labels = proto.Field( + proto.MESSAGE, + number=18, + oneof="dimension", + message="ProductLabelsInfo", + ) + product_legacy_condition = proto.Field( + proto.MESSAGE, + number=19, + oneof="dimension", + message="ProductLegacyConditionInfo", + ) + product_type_full = proto.Field( + proto.MESSAGE, + number=20, + oneof="dimension", + message="ProductTypeFullInfo", + ) + unknown_listing_dimension = proto.Field( + proto.MESSAGE, + number=14, + oneof="dimension", + message="UnknownListingDimensionInfo", + ) + + +class HotelIdInfo(proto.Message): + r"""Advertiser-specific hotel ID. + + Attributes: + value (str): + String value of the hotel ID. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=2, optional=True,) + + +class HotelClassInfo(proto.Message): + r"""Class of the hotel as a number of stars 1 to 5. + + Attributes: + value (int): + Long value of the hotel class. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.INT64, number=2, optional=True,) + + +class HotelCountryRegionInfo(proto.Message): + r"""Country or Region the hotel is located in. + + Attributes: + country_region_criterion (str): + The Geo Target Constant resource name. + + This field is a member of `oneof`_ ``_country_region_criterion``. + """ + + country_region_criterion = proto.Field( + proto.STRING, number=2, optional=True, + ) + + +class HotelStateInfo(proto.Message): + r"""State the hotel is located in. + + Attributes: + state_criterion (str): + The Geo Target Constant resource name. + + This field is a member of `oneof`_ ``_state_criterion``. + """ + + state_criterion = proto.Field(proto.STRING, number=2, optional=True,) + + +class HotelCityInfo(proto.Message): + r"""City the hotel is located in. + + Attributes: + city_criterion (str): + The Geo Target Constant resource name. + + This field is a member of `oneof`_ ``_city_criterion``. + """ + + city_criterion = proto.Field(proto.STRING, number=2, optional=True,) + + +class ProductBiddingCategoryInfo(proto.Message): + r"""Bidding category of a product offer. + + Attributes: + id (int): + ID of the product bidding category. + + This ID is equivalent to the google_product_category ID as + described in this article: + https://support.google.com/merchants/answer/6324436 + + This field is a member of `oneof`_ ``_id``. + country_code (str): + Two-letter upper-case country code of the product bidding + category. It must match the + campaign.shopping_setting.sales_country field. + + This field is a member of `oneof`_ ``_country_code``. + level (google.ads.googleads.v12.enums.types.ProductBiddingCategoryLevelEnum.ProductBiddingCategoryLevel): + Level of the product bidding category. + """ + + id = proto.Field(proto.INT64, number=4, optional=True,) + country_code = proto.Field(proto.STRING, number=5, optional=True,) + level = proto.Field( + proto.ENUM, + number=3, + enum=product_bidding_category_level.ProductBiddingCategoryLevelEnum.ProductBiddingCategoryLevel, + ) + + +class ProductBrandInfo(proto.Message): + r"""Brand of the product. + + Attributes: + value (str): + String value of the product brand. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=2, optional=True,) + + +class ProductChannelInfo(proto.Message): + r"""Locality of a product offer. + + Attributes: + channel (google.ads.googleads.v12.enums.types.ProductChannelEnum.ProductChannel): + Value of the locality. + """ + + channel = proto.Field( + proto.ENUM, + number=1, + enum=gage_product_channel.ProductChannelEnum.ProductChannel, + ) + + +class ProductChannelExclusivityInfo(proto.Message): + r"""Availability of a product offer. + + Attributes: + channel_exclusivity (google.ads.googleads.v12.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): + Value of the availability. + """ + + channel_exclusivity = proto.Field( + proto.ENUM, + number=1, + enum=gage_product_channel_exclusivity.ProductChannelExclusivityEnum.ProductChannelExclusivity, + ) + + +class ProductConditionInfo(proto.Message): + r"""Condition of a product offer. + + Attributes: + condition (google.ads.googleads.v12.enums.types.ProductConditionEnum.ProductCondition): + Value of the condition. + """ + + condition = proto.Field( + proto.ENUM, + number=1, + enum=gage_product_condition.ProductConditionEnum.ProductCondition, + ) + + +class ProductCustomAttributeInfo(proto.Message): + r"""Custom attribute of a product offer. + + Attributes: + value (str): + String value of the product custom attribute. + + This field is a member of `oneof`_ ``_value``. + index (google.ads.googleads.v12.enums.types.ProductCustomAttributeIndexEnum.ProductCustomAttributeIndex): + Indicates the index of the custom attribute. + """ + + value = proto.Field(proto.STRING, number=3, optional=True,) + index = proto.Field( + proto.ENUM, + number=2, + enum=product_custom_attribute_index.ProductCustomAttributeIndexEnum.ProductCustomAttributeIndex, + ) + + +class ProductItemIdInfo(proto.Message): + r"""Item id of a product offer. + + Attributes: + value (str): + Value of the id. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=2, optional=True,) + + +class ProductTypeInfo(proto.Message): + r"""Type of a product offer. + + Attributes: + value (str): + Value of the type. + + This field is a member of `oneof`_ ``_value``. + level (google.ads.googleads.v12.enums.types.ProductTypeLevelEnum.ProductTypeLevel): + Level of the type. + """ + + value = proto.Field(proto.STRING, number=3, optional=True,) + level = proto.Field( + proto.ENUM, + number=2, + enum=product_type_level.ProductTypeLevelEnum.ProductTypeLevel, + ) + + +class ProductGroupingInfo(proto.Message): + r"""Grouping of a product offer. This listing dimension is + deprecated and it is supported only in Display campaigns. + + Attributes: + value (str): + String value of the product grouping. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + +class ProductLabelsInfo(proto.Message): + r"""Labels of a product offer. This listing dimension is + deprecated and it is supported only in Display campaigns. + + Attributes: + value (str): + String value of the product labels. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + +class ProductLegacyConditionInfo(proto.Message): + r"""Legacy condition of a product offer. This listing dimension + is deprecated and it is supported only in Display campaigns. + + Attributes: + value (str): + String value of the product legacy condition. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + +class ProductTypeFullInfo(proto.Message): + r"""Full type of a product offer. This listing dimension is + deprecated and it is supported only in Display campaigns. + + Attributes: + value (str): + String value of the product full type. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + +class UnknownListingDimensionInfo(proto.Message): + r"""Unknown listing dimension. + """ + + +class HotelDateSelectionTypeInfo(proto.Message): + r"""Criterion for hotel date selection (default dates versus user + selected). + + Attributes: + type_ (google.ads.googleads.v12.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): + Type of the hotel date selection + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=hotel_date_selection_type.HotelDateSelectionTypeEnum.HotelDateSelectionType, + ) + + +class HotelAdvanceBookingWindowInfo(proto.Message): + r"""Criterion for number of days prior to the stay the booking is + being made. + + Attributes: + min_days (int): + Low end of the number of days prior to the + stay. + + This field is a member of `oneof`_ ``_min_days``. + max_days (int): + High end of the number of days prior to the + stay. + + This field is a member of `oneof`_ ``_max_days``. + """ + + min_days = proto.Field(proto.INT64, number=3, optional=True,) + max_days = proto.Field(proto.INT64, number=4, optional=True,) + + +class HotelLengthOfStayInfo(proto.Message): + r"""Criterion for length of hotel stay in nights. + + Attributes: + min_nights (int): + Low end of the number of nights in the stay. + + This field is a member of `oneof`_ ``_min_nights``. + max_nights (int): + High end of the number of nights in the stay. + + This field is a member of `oneof`_ ``_max_nights``. + """ + + min_nights = proto.Field(proto.INT64, number=3, optional=True,) + max_nights = proto.Field(proto.INT64, number=4, optional=True,) + + +class HotelCheckInDateRangeInfo(proto.Message): + r"""Criterion for a check-in date range. + + Attributes: + start_date (str): + Start date in the YYYY-MM-DD format. + end_date (str): + End date in the YYYY-MM-DD format. + """ + + start_date = proto.Field(proto.STRING, number=1,) + end_date = proto.Field(proto.STRING, number=2,) + + +class HotelCheckInDayInfo(proto.Message): + r"""Criterion for day of the week the booking is for. + + Attributes: + day_of_week (google.ads.googleads.v12.enums.types.DayOfWeekEnum.DayOfWeek): + The day of the week. + """ + + day_of_week = proto.Field( + proto.ENUM, number=1, enum=gage_day_of_week.DayOfWeekEnum.DayOfWeek, + ) + + +class InteractionTypeInfo(proto.Message): + r"""Criterion for Interaction Type. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.InteractionTypeEnum.InteractionType): + The interaction type. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=interaction_type.InteractionTypeEnum.InteractionType, + ) + + +class AdScheduleInfo(proto.Message): + r"""Represents an AdSchedule criterion. + AdSchedule is specified as the day of the week and a time + interval within which ads will be shown. + + No more than six AdSchedules can be added for the same day. + + Attributes: + start_minute (google.ads.googleads.v12.enums.types.MinuteOfHourEnum.MinuteOfHour): + Minutes after the start hour at which this + schedule starts. + This field is required for CREATE operations and + is prohibited on UPDATE operations. + end_minute (google.ads.googleads.v12.enums.types.MinuteOfHourEnum.MinuteOfHour): + Minutes after the end hour at which this + schedule ends. The schedule is exclusive of the + end minute. + This field is required for CREATE operations and + is prohibited on UPDATE operations. + start_hour (int): + Starting hour in 24 hour time. + This field must be between 0 and 23, inclusive. + This field is required for CREATE operations and + is prohibited on UPDATE operations. + + This field is a member of `oneof`_ ``_start_hour``. + end_hour (int): + Ending hour in 24 hour time; 24 signifies end + of the day. This field must be between 0 and 24, + inclusive. + This field is required for CREATE operations and + is prohibited on UPDATE operations. + + This field is a member of `oneof`_ ``_end_hour``. + day_of_week (google.ads.googleads.v12.enums.types.DayOfWeekEnum.DayOfWeek): + Day of the week the schedule applies to. + This field is required for CREATE operations and + is prohibited on UPDATE operations. + """ + + start_minute = proto.Field( + proto.ENUM, number=1, enum=minute_of_hour.MinuteOfHourEnum.MinuteOfHour, + ) + end_minute = proto.Field( + proto.ENUM, number=2, enum=minute_of_hour.MinuteOfHourEnum.MinuteOfHour, + ) + start_hour = proto.Field(proto.INT32, number=6, optional=True,) + end_hour = proto.Field(proto.INT32, number=7, optional=True,) + day_of_week = proto.Field( + proto.ENUM, number=5, enum=gage_day_of_week.DayOfWeekEnum.DayOfWeek, + ) + + +class AgeRangeInfo(proto.Message): + r"""An age range criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.AgeRangeTypeEnum.AgeRangeType): + Type of the age range. + """ + + type_ = proto.Field( + proto.ENUM, number=1, enum=age_range_type.AgeRangeTypeEnum.AgeRangeType, + ) + + +class GenderInfo(proto.Message): + r"""A gender criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.GenderTypeEnum.GenderType): + Type of the gender. + """ + + type_ = proto.Field( + proto.ENUM, number=1, enum=gender_type.GenderTypeEnum.GenderType, + ) + + +class IncomeRangeInfo(proto.Message): + r"""An income range criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.IncomeRangeTypeEnum.IncomeRangeType): + Type of the income range. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=income_range_type.IncomeRangeTypeEnum.IncomeRangeType, + ) + + +class ParentalStatusInfo(proto.Message): + r"""A parental status criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.ParentalStatusTypeEnum.ParentalStatusType): + Type of the parental status. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=parental_status_type.ParentalStatusTypeEnum.ParentalStatusType, + ) + + +class YouTubeVideoInfo(proto.Message): + r"""A YouTube Video criterion. + + Attributes: + video_id (str): + YouTube video id as it appears on the YouTube + watch page. + + This field is a member of `oneof`_ ``_video_id``. + """ + + video_id = proto.Field(proto.STRING, number=2, optional=True,) + + +class YouTubeChannelInfo(proto.Message): + r"""A YouTube Channel criterion. + + Attributes: + channel_id (str): + The YouTube uploader channel id or the + channel code of a YouTube channel. + + This field is a member of `oneof`_ ``_channel_id``. + """ + + channel_id = proto.Field(proto.STRING, number=2, optional=True,) + + +class UserListInfo(proto.Message): + r"""A User List criterion. Represents a user list that is defined + by the advertiser to be targeted. + + Attributes: + user_list (str): + The User List resource name. + + This field is a member of `oneof`_ ``_user_list``. + """ + + user_list = proto.Field(proto.STRING, number=2, optional=True,) + + +class ProximityInfo(proto.Message): + r"""A Proximity criterion. The geo point and radius determine + what geographical area is included. The address is a description + of the geo point that does not affect ad serving. + + There are two ways to create a proximity. First, by setting an + address and radius. The geo point will be automatically + computed. Second, by setting a geo point and radius. The address + is an optional label that won't be validated. + + Attributes: + geo_point (google.ads.googleads.v12.common.types.GeoPointInfo): + Latitude and longitude. + radius (float): + The radius of the proximity. + + This field is a member of `oneof`_ ``_radius``. + radius_units (google.ads.googleads.v12.enums.types.ProximityRadiusUnitsEnum.ProximityRadiusUnits): + The unit of measurement of the radius. + Default is KILOMETERS. + address (google.ads.googleads.v12.common.types.AddressInfo): + Full address. + """ + + geo_point = proto.Field(proto.MESSAGE, number=1, message="GeoPointInfo",) + radius = proto.Field(proto.DOUBLE, number=5, optional=True,) + radius_units = proto.Field( + proto.ENUM, + number=3, + enum=proximity_radius_units.ProximityRadiusUnitsEnum.ProximityRadiusUnits, + ) + address = proto.Field(proto.MESSAGE, number=4, message="AddressInfo",) + + +class GeoPointInfo(proto.Message): + r"""Geo point for proximity criterion. + + Attributes: + longitude_in_micro_degrees (int): + Micro degrees for the longitude. + + This field is a member of `oneof`_ ``_longitude_in_micro_degrees``. + latitude_in_micro_degrees (int): + Micro degrees for the latitude. + + This field is a member of `oneof`_ ``_latitude_in_micro_degrees``. + """ + + longitude_in_micro_degrees = proto.Field( + proto.INT32, number=3, optional=True, + ) + latitude_in_micro_degrees = proto.Field( + proto.INT32, number=4, optional=True, + ) + + +class AddressInfo(proto.Message): + r"""Address for proximity criterion. + + Attributes: + postal_code (str): + Postal code. + + This field is a member of `oneof`_ ``_postal_code``. + province_code (str): + Province or state code. + + This field is a member of `oneof`_ ``_province_code``. + country_code (str): + Country code. + + This field is a member of `oneof`_ ``_country_code``. + province_name (str): + Province or state name. + + This field is a member of `oneof`_ ``_province_name``. + street_address (str): + Street address line 1. + + This field is a member of `oneof`_ ``_street_address``. + street_address2 (str): + Street address line 2. This field is write-only. It is only + used for calculating the longitude and latitude of an + address when geo_point is empty. + + This field is a member of `oneof`_ ``_street_address2``. + city_name (str): + Name of the city. + + This field is a member of `oneof`_ ``_city_name``. + """ + + postal_code = proto.Field(proto.STRING, number=8, optional=True,) + province_code = proto.Field(proto.STRING, number=9, optional=True,) + country_code = proto.Field(proto.STRING, number=10, optional=True,) + province_name = proto.Field(proto.STRING, number=11, optional=True,) + street_address = proto.Field(proto.STRING, number=12, optional=True,) + street_address2 = proto.Field(proto.STRING, number=13, optional=True,) + city_name = proto.Field(proto.STRING, number=14, optional=True,) + + +class TopicInfo(proto.Message): + r"""A topic criterion. Use topics to target or exclude placements + in the Google Display Network based on the category into which + the placement falls (for example, "Pets & Animals/Pets/Dogs"). + + Attributes: + topic_constant (str): + The Topic Constant resource name. + + This field is a member of `oneof`_ ``_topic_constant``. + path (Sequence[str]): + The category to target or exclude. Each + subsequent element in the array describes a more + specific sub-category. For example, "Pets & + Animals", "Pets", "Dogs" represents the "Pets & + Animals/Pets/Dogs" category. + """ + + topic_constant = proto.Field(proto.STRING, number=3, optional=True,) + path = proto.RepeatedField(proto.STRING, number=4,) + + +class LanguageInfo(proto.Message): + r"""A language criterion. + + Attributes: + language_constant (str): + The language constant resource name. + + This field is a member of `oneof`_ ``_language_constant``. + """ + + language_constant = proto.Field(proto.STRING, number=2, optional=True,) + + +class IpBlockInfo(proto.Message): + r"""An IpBlock criterion used for IP exclusions. We allow: + - IPv4 and IPv6 addresses + - individual addresses (192.168.0.1) + - masks for individual addresses (192.168.0.1/32) + - masks for Class C networks (192.168.0.1/24) + + Attributes: + ip_address (str): + The IP address of this IP block. + + This field is a member of `oneof`_ ``_ip_address``. + """ + + ip_address = proto.Field(proto.STRING, number=2, optional=True,) + + +class ContentLabelInfo(proto.Message): + r"""Content Label for category exclusion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.ContentLabelTypeEnum.ContentLabelType): + Content label type, required for CREATE + operations. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=content_label_type.ContentLabelTypeEnum.ContentLabelType, + ) + + +class CarrierInfo(proto.Message): + r"""Represents a Carrier Criterion. + + Attributes: + carrier_constant (str): + The Carrier constant resource name. + + This field is a member of `oneof`_ ``_carrier_constant``. + """ + + carrier_constant = proto.Field(proto.STRING, number=2, optional=True,) + + +class UserInterestInfo(proto.Message): + r"""Represents a particular interest-based topic to be targeted. + + Attributes: + user_interest_category (str): + The UserInterest resource name. + + This field is a member of `oneof`_ ``_user_interest_category``. + """ + + user_interest_category = proto.Field(proto.STRING, number=2, optional=True,) + + +class WebpageInfo(proto.Message): + r"""Represents a criterion for targeting webpages of an + advertiser's website. + + Attributes: + criterion_name (str): + The name of the criterion that is defined by + this parameter. The name value will be used for + identifying, sorting and filtering criteria with + this type of parameters. + + This field is required for CREATE operations and + is prohibited on UPDATE operations. + + This field is a member of `oneof`_ ``_criterion_name``. + conditions (Sequence[google.ads.googleads.v12.common.types.WebpageConditionInfo]): + Conditions, or logical expressions, for + webpage targeting. The list of webpage targeting + conditions are and-ed together when evaluated + for targeting. An empty list of conditions + indicates all pages of the campaign's website + are targeted. + + This field is required for CREATE operations and + is prohibited on UPDATE operations. + coverage_percentage (float): + Website criteria coverage percentage. This is + the computed percentage of website coverage + based on the website target, negative website + target and negative keywords in the ad group and + campaign. For instance, when coverage returns as + 1, it indicates it has 100% coverage. This field + is read-only. + sample (google.ads.googleads.v12.common.types.WebpageSampleInfo): + List of sample urls that match the website + target. This field is read-only. + """ + + criterion_name = proto.Field(proto.STRING, number=3, optional=True,) + conditions = proto.RepeatedField( + proto.MESSAGE, number=2, message="WebpageConditionInfo", + ) + coverage_percentage = proto.Field(proto.DOUBLE, number=4,) + sample = proto.Field(proto.MESSAGE, number=5, message="WebpageSampleInfo",) + + +class WebpageConditionInfo(proto.Message): + r"""Logical expression for targeting webpages of an advertiser's + website. + + Attributes: + operand (google.ads.googleads.v12.enums.types.WebpageConditionOperandEnum.WebpageConditionOperand): + Operand of webpage targeting condition. + operator (google.ads.googleads.v12.enums.types.WebpageConditionOperatorEnum.WebpageConditionOperator): + Operator of webpage targeting condition. + argument (str): + Argument of webpage targeting condition. + + This field is a member of `oneof`_ ``_argument``. + """ + + operand = proto.Field( + proto.ENUM, + number=1, + enum=webpage_condition_operand.WebpageConditionOperandEnum.WebpageConditionOperand, + ) + operator = proto.Field( + proto.ENUM, + number=2, + enum=webpage_condition_operator.WebpageConditionOperatorEnum.WebpageConditionOperator, + ) + argument = proto.Field(proto.STRING, number=4, optional=True,) + + +class WebpageSampleInfo(proto.Message): + r"""List of sample urls that match the website target + + Attributes: + sample_urls (Sequence[str]): + Webpage sample urls + """ + + sample_urls = proto.RepeatedField(proto.STRING, number=1,) + + +class OperatingSystemVersionInfo(proto.Message): + r"""Represents an operating system version to be targeted. + + Attributes: + operating_system_version_constant (str): + The operating system version constant + resource name. + + This field is a member of `oneof`_ ``_operating_system_version_constant``. + """ + + operating_system_version_constant = proto.Field( + proto.STRING, number=2, optional=True, + ) + + +class AppPaymentModelInfo(proto.Message): + r"""An app payment model criterion. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.AppPaymentModelTypeEnum.AppPaymentModelType): + Type of the app payment model. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=app_payment_model_type.AppPaymentModelTypeEnum.AppPaymentModelType, + ) + + +class MobileDeviceInfo(proto.Message): + r"""A mobile device criterion. + + Attributes: + mobile_device_constant (str): + The mobile device constant resource name. + + This field is a member of `oneof`_ ``_mobile_device_constant``. + """ + + mobile_device_constant = proto.Field(proto.STRING, number=2, optional=True,) + + +class CustomAffinityInfo(proto.Message): + r"""A custom affinity criterion. + A criterion of this type is only targetable. + + Attributes: + custom_affinity (str): + The CustomInterest resource name. + + This field is a member of `oneof`_ ``_custom_affinity``. + """ + + custom_affinity = proto.Field(proto.STRING, number=2, optional=True,) + + +class CustomIntentInfo(proto.Message): + r"""A custom intent criterion. + A criterion of this type is only targetable. + + Attributes: + custom_intent (str): + The CustomInterest resource name. + + This field is a member of `oneof`_ ``_custom_intent``. + """ + + custom_intent = proto.Field(proto.STRING, number=2, optional=True,) + + +class LocationGroupInfo(proto.Message): + r"""A radius around a list of locations specified through a feed + or assetSet. + + Attributes: + feed (str): + Feed specifying locations for targeting. + Cannot be set with AssetSet fields. This is + required and must be set in CREATE operations. + + This field is a member of `oneof`_ ``_feed``. + geo_target_constants (Sequence[str]): + Geo target constant(s) restricting the scope + of the geographic area within the feed. + Currently only one geo target constant is + allowed. Cannot be set with AssetSet fields. + radius (int): + Distance in units specifying the radius + around targeted locations. This is required and + must be set in CREATE operations. + + This field is a member of `oneof`_ ``_radius``. + radius_units (google.ads.googleads.v12.enums.types.LocationGroupRadiusUnitsEnum.LocationGroupRadiusUnits): + Unit of the radius. Miles and meters are + supported for geo target constants. Milli miles + and meters are supported for feed item sets and + asset sets. This is required and must be set in + CREATE operations. + feed_item_sets (Sequence[str]): + FeedItemSets whose FeedItems are targeted. If multiple IDs + are specified, then all items that appear in at least one + set are targeted. This field cannot be used with + geo_target_constants. This is optional and can only be set + in CREATE operations. Cannot be set with AssetSet fields. + enable_customer_level_location_asset_set (bool): + Denotes that the latest customer level asset set is used for + targeting. Used with radius and radius_units. Cannot be used + with feed, geo target constants or feed item sets. When + using asset sets, either this field or + location_group_asset_sets should be specified. Both cannot + be used at the same time. This can only be set in CREATE + operations. + + This field is a member of `oneof`_ ``_enable_customer_level_location_asset_set``. + location_group_asset_sets (Sequence[str]): + AssetSets whose Assets are targeted. If multiple IDs are + specified, then all items that appear in at least one set + are targeted. This field cannot be used with feed, geo + target constants or feed item sets. When using asset sets, + either this field or + enable_customer_level_location_asset_set should be + specified. Both cannot be used at the same time. This can + only be set in CREATE operations. + """ + + feed = proto.Field(proto.STRING, number=5, optional=True,) + geo_target_constants = proto.RepeatedField(proto.STRING, number=6,) + radius = proto.Field(proto.INT64, number=7, optional=True,) + radius_units = proto.Field( + proto.ENUM, + number=4, + enum=location_group_radius_units.LocationGroupRadiusUnitsEnum.LocationGroupRadiusUnits, + ) + feed_item_sets = proto.RepeatedField(proto.STRING, number=8,) + enable_customer_level_location_asset_set = proto.Field( + proto.BOOL, number=9, optional=True, + ) + location_group_asset_sets = proto.RepeatedField(proto.STRING, number=10,) + + +class CustomAudienceInfo(proto.Message): + r"""A custom audience criterion. + + Attributes: + custom_audience (str): + The CustomAudience resource name. + """ + + custom_audience = proto.Field(proto.STRING, number=1,) + + +class CombinedAudienceInfo(proto.Message): + r"""A combined audience criterion. + + Attributes: + combined_audience (str): + The CombinedAudience resource name. + """ + + combined_audience = proto.Field(proto.STRING, number=1,) + + +class AudienceInfo(proto.Message): + r"""An audience criterion. + + Attributes: + audience (str): + The Audience resource name. + """ + + audience = proto.Field(proto.STRING, number=1,) + + +class KeywordThemeInfo(proto.Message): + r"""A Smart Campaign keyword theme. + + 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: + keyword_theme_constant (str): + The resource name of a Smart Campaign keyword theme + constant. + ``keywordThemeConstants/{keyword_theme_id}~{sub_keyword_theme_id}`` + + This field is a member of `oneof`_ ``keyword_theme``. + free_form_keyword_theme (str): + Free-form text to be matched to a Smart + Campaign keyword theme constant on a best-effort + basis. + + This field is a member of `oneof`_ ``keyword_theme``. + """ + + keyword_theme_constant = proto.Field( + proto.STRING, number=1, oneof="keyword_theme", + ) + free_form_keyword_theme = proto.Field( + proto.STRING, number=2, oneof="keyword_theme", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/criterion_category_availability.py b/google/ads/googleads/v12/common/types/criterion_category_availability.py new file mode 100644 index 000000000..75b143867 --- /dev/null +++ b/google/ads/googleads/v12/common/types/criterion_category_availability.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + advertising_channel_sub_type as gage_advertising_channel_sub_type, +) +from google.ads.googleads.v12.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v12.enums.types import ( + criterion_category_channel_availability_mode, +) +from google.ads.googleads.v12.enums.types import ( + criterion_category_locale_availability_mode, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "CriterionCategoryAvailability", + "CriterionCategoryChannelAvailability", + "CriterionCategoryLocaleAvailability", + }, +) + + +class CriterionCategoryAvailability(proto.Message): + r"""Information of category availability, per advertising + channel. + + Attributes: + channel (google.ads.googleads.v12.common.types.CriterionCategoryChannelAvailability): + Channel types and subtypes that are available + to the category. + locale (Sequence[google.ads.googleads.v12.common.types.CriterionCategoryLocaleAvailability]): + Locales that are available to the category + for the channel. + """ + + channel = proto.Field( + proto.MESSAGE, number=1, message="CriterionCategoryChannelAvailability", + ) + locale = proto.RepeatedField( + proto.MESSAGE, number=2, message="CriterionCategoryLocaleAvailability", + ) + + +class CriterionCategoryChannelAvailability(proto.Message): + r"""Information of advertising channel type and subtypes a + category is available in. + + Attributes: + availability_mode (google.ads.googleads.v12.enums.types.CriterionCategoryChannelAvailabilityModeEnum.CriterionCategoryChannelAvailabilityMode): + Format of the channel availability. Can be ALL_CHANNELS (the + rest of the fields will not be set), CHANNEL_TYPE (only + advertising_channel_type type will be set, the category is + available to all sub types under it) or + CHANNEL_TYPE_AND_SUBTYPES (advertising_channel_type, + advertising_channel_sub_type, and + include_default_channel_sub_type will all be set). + advertising_channel_type (google.ads.googleads.v12.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Channel type the category is available to. + advertising_channel_sub_type (Sequence[google.ads.googleads.v12.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType]): + Channel subtypes under the channel type the + category is available to. + include_default_channel_sub_type (bool): + Whether default channel sub type is included. For example, + advertising_channel_type being DISPLAY and + include_default_channel_sub_type being false means that the + default display campaign where channel sub type is not set + is not included in this availability configuration. + + This field is a member of `oneof`_ ``_include_default_channel_sub_type``. + """ + + availability_mode = proto.Field( + proto.ENUM, + number=1, + enum=criterion_category_channel_availability_mode.CriterionCategoryChannelAvailabilityModeEnum.CriterionCategoryChannelAvailabilityMode, + ) + advertising_channel_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + advertising_channel_sub_type = proto.RepeatedField( + proto.ENUM, + number=3, + enum=gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType, + ) + include_default_channel_sub_type = proto.Field( + proto.BOOL, number=5, optional=True, + ) + + +class CriterionCategoryLocaleAvailability(proto.Message): + r"""Information about which locales a category is available in. + + Attributes: + availability_mode (google.ads.googleads.v12.enums.types.CriterionCategoryLocaleAvailabilityModeEnum.CriterionCategoryLocaleAvailabilityMode): + Format of the locale availability. Can be LAUNCHED_TO_ALL + (both country and language will be empty), COUNTRY (only + country will be set), LANGUAGE (only language wil be set), + COUNTRY_AND_LANGUAGE (both country and language will be + set). + country_code (str): + Code of the country. + + This field is a member of `oneof`_ ``_country_code``. + language_code (str): + Code of the language. + + This field is a member of `oneof`_ ``_language_code``. + """ + + availability_mode = proto.Field( + proto.ENUM, + number=1, + enum=criterion_category_locale_availability_mode.CriterionCategoryLocaleAvailabilityModeEnum.CriterionCategoryLocaleAvailabilityMode, + ) + country_code = proto.Field(proto.STRING, number=4, optional=True,) + language_code = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/custom_parameter.py b/google/ads/googleads/v12/common/types/custom_parameter.py new file mode 100644 index 000000000..0cac3986a --- /dev/null +++ b/google/ads/googleads/v12/common/types/custom_parameter.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"CustomParameter",}, +) + + +class CustomParameter(proto.Message): + r"""A mapping that can be used by custom parameter tags in a + ``tracking_url_template``, ``final_urls``, or ``mobile_final_urls``. + + Attributes: + key (str): + The key matching the parameter tag name. + + This field is a member of `oneof`_ ``_key``. + value (str): + The value to be substituted. + + This field is a member of `oneof`_ ``_value``. + """ + + key = proto.Field(proto.STRING, number=3, optional=True,) + value = proto.Field(proto.STRING, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/customizer_value.py b/google/ads/googleads/v12/common/types/customizer_value.py new file mode 100644 index 000000000..d3752ecaf --- /dev/null +++ b/google/ads/googleads/v12/common/types/customizer_value.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import customizer_attribute_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"CustomizerValue",}, +) + + +class CustomizerValue(proto.Message): + r"""A customizer value that is referenced in customizer linkage + entities like CustomerCustomizer, CampaignCustomizer, etc. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): + Required. The data type for the customizer value. It must + match the attribute type. The string_value content must + match the constraints associated with the type. + string_value (str): + Required. Value to insert in creative text. + Customizer values of all types are stored as + string to make formatting unambiguous. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=customizer_attribute_type.CustomizerAttributeTypeEnum.CustomizerAttributeType, + ) + string_value = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/dates.py b/google/ads/googleads/v12/common/types/dates.py new file mode 100644 index 000000000..ec6978fdf --- /dev/null +++ b/google/ads/googleads/v12/common/types/dates.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import month_of_year + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"DateRange", "YearMonthRange", "YearMonth",}, +) + + +class DateRange(proto.Message): + r"""A date range. + + Attributes: + start_date (str): + The start date, in yyyy-mm-dd format. This + date is inclusive. + + This field is a member of `oneof`_ ``_start_date``. + end_date (str): + The end date, in yyyy-mm-dd format. This date + is inclusive. + + This field is a member of `oneof`_ ``_end_date``. + """ + + start_date = proto.Field(proto.STRING, number=3, optional=True,) + end_date = proto.Field(proto.STRING, number=4, optional=True,) + + +class YearMonthRange(proto.Message): + r"""The year month range inclusive of the start and end months. + Eg: A year month range to represent Jan 2020 would be: (Jan + 2020, Jan 2020). + + Attributes: + start (google.ads.googleads.v12.common.types.YearMonth): + The inclusive start year month. + end (google.ads.googleads.v12.common.types.YearMonth): + The inclusive end year month. + """ + + start = proto.Field(proto.MESSAGE, number=1, message="YearMonth",) + end = proto.Field(proto.MESSAGE, number=2, message="YearMonth",) + + +class YearMonth(proto.Message): + r"""Year month. + + Attributes: + year (int): + The year (for example, 2020). + month (google.ads.googleads.v12.enums.types.MonthOfYearEnum.MonthOfYear): + The month of the year. (for example, + FEBRUARY). + """ + + year = proto.Field(proto.INT64, number=1,) + month = proto.Field( + proto.ENUM, number=2, enum=month_of_year.MonthOfYearEnum.MonthOfYear, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/explorer_auto_optimizer_setting.py b/google/ads/googleads/v12/common/types/explorer_auto_optimizer_setting.py new file mode 100644 index 000000000..cc38535fa --- /dev/null +++ b/google/ads/googleads/v12/common/types/explorer_auto_optimizer_setting.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"ExplorerAutoOptimizerSetting",}, +) + + +class ExplorerAutoOptimizerSetting(proto.Message): + r"""Settings for the Display Campaign Optimizer, initially named + "Explorer". Learn more about `automatic + targeting `__. + + Attributes: + opt_in (bool): + Indicates whether the optimizer is turned on. + + This field is a member of `oneof`_ ``_opt_in``. + """ + + opt_in = proto.Field(proto.BOOL, number=2, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/extensions.py b/google/ads/googleads/v12/common/types/extensions.py new file mode 100644 index 000000000..fc99b7bdb --- /dev/null +++ b/google/ads/googleads/v12/common/types/extensions.py @@ -0,0 +1,635 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import feed_common +from google.ads.googleads.v12.enums.types import app_store as gage_app_store +from google.ads.googleads.v12.enums.types import ( + call_conversion_reporting_state as gage_call_conversion_reporting_state, +) +from google.ads.googleads.v12.enums.types import price_extension_price_qualifier +from google.ads.googleads.v12.enums.types import price_extension_price_unit +from google.ads.googleads.v12.enums.types import price_extension_type +from google.ads.googleads.v12.enums.types import ( + promotion_extension_discount_modifier, +) +from google.ads.googleads.v12.enums.types import promotion_extension_occasion + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "AppFeedItem", + "CallFeedItem", + "CalloutFeedItem", + "LocationFeedItem", + "AffiliateLocationFeedItem", + "TextMessageFeedItem", + "PriceFeedItem", + "PriceOffer", + "PromotionFeedItem", + "StructuredSnippetFeedItem", + "SitelinkFeedItem", + "HotelCalloutFeedItem", + "ImageFeedItem", + }, +) + + +class AppFeedItem(proto.Message): + r"""Represents an App extension. + + Attributes: + link_text (str): + The visible text displayed when the link is + rendered in an ad. This string must not be + empty, and the length of this string should be + between 1 and 25, inclusive. + + This field is a member of `oneof`_ ``_link_text``. + app_id (str): + The store-specific ID for the target + application. This string must not be empty. + + This field is a member of `oneof`_ ``_app_id``. + app_store (google.ads.googleads.v12.enums.types.AppStoreEnum.AppStore): + The application store that the target + application belongs to. This field is required. + final_urls (Sequence[str]): + A list of possible final URLs after all cross + domain redirects. This list must not be empty. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs after + all cross domain redirects. + tracking_url_template (str): + URL template for constructing a tracking URL. + Default value is "{lpurl}". + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + A list of mappings to be used for substituting URL custom + parameter tags in the tracking_url_template, final_urls, + and/or final_mobile_urls. + final_url_suffix (str): + URL template for appending params to landing + page URLs served with parallel tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + """ + + link_text = proto.Field(proto.STRING, number=9, optional=True,) + app_id = proto.Field(proto.STRING, number=10, optional=True,) + app_store = proto.Field( + proto.ENUM, number=3, enum=gage_app_store.AppStoreEnum.AppStore, + ) + final_urls = proto.RepeatedField(proto.STRING, number=11,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=12,) + tracking_url_template = proto.Field(proto.STRING, number=13, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=7, message=custom_parameter.CustomParameter, + ) + final_url_suffix = proto.Field(proto.STRING, number=14, optional=True,) + + +class CallFeedItem(proto.Message): + r"""Represents a Call extension. + + Attributes: + phone_number (str): + The advertiser's phone number to append to + the ad. This string must not be empty. + + This field is a member of `oneof`_ ``_phone_number``. + country_code (str): + Uppercase two-letter country code of the + advertiser's phone number. This string must not + be empty. + + This field is a member of `oneof`_ ``_country_code``. + call_tracking_enabled (bool): + Indicates whether call tracking is enabled. + By default, call tracking is not enabled. + + This field is a member of `oneof`_ ``_call_tracking_enabled``. + call_conversion_action (str): + The conversion action to attribute a call conversion to. If + not set a default conversion action is used. This field only + has effect if call_tracking_enabled is set to true. + Otherwise this field is ignored. + + This field is a member of `oneof`_ ``_call_conversion_action``. + call_conversion_tracking_disabled (bool): + If true, disable call conversion tracking. + call_conversion_action should not be set if this is true. + Optional. + + This field is a member of `oneof`_ ``_call_conversion_tracking_disabled``. + call_conversion_reporting_state (google.ads.googleads.v12.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): + Enum value that indicates whether this call + extension uses its own call conversion setting + (or just have call conversion disabled), or + following the account level setting. + """ + + phone_number = proto.Field(proto.STRING, number=7, optional=True,) + country_code = proto.Field(proto.STRING, number=8, optional=True,) + call_tracking_enabled = proto.Field(proto.BOOL, number=9, optional=True,) + call_conversion_action = proto.Field( + proto.STRING, number=10, optional=True, + ) + call_conversion_tracking_disabled = proto.Field( + proto.BOOL, number=11, optional=True, + ) + call_conversion_reporting_state = proto.Field( + proto.ENUM, + number=6, + enum=gage_call_conversion_reporting_state.CallConversionReportingStateEnum.CallConversionReportingState, + ) + + +class CalloutFeedItem(proto.Message): + r"""Represents a callout extension. + + Attributes: + callout_text (str): + The callout text. + The length of this string should be between 1 + and 25, inclusive. + + This field is a member of `oneof`_ ``_callout_text``. + """ + + callout_text = proto.Field(proto.STRING, number=2, optional=True,) + + +class LocationFeedItem(proto.Message): + r"""Represents a location extension. + + Attributes: + business_name (str): + The name of the business. + + This field is a member of `oneof`_ ``_business_name``. + address_line_1 (str): + Line 1 of the business address. + + This field is a member of `oneof`_ ``_address_line_1``. + address_line_2 (str): + Line 2 of the business address. + + This field is a member of `oneof`_ ``_address_line_2``. + city (str): + City of the business address. + + This field is a member of `oneof`_ ``_city``. + province (str): + Province of the business address. + + This field is a member of `oneof`_ ``_province``. + postal_code (str): + Postal code of the business address. + + This field is a member of `oneof`_ ``_postal_code``. + country_code (str): + Country code of the business address. + + This field is a member of `oneof`_ ``_country_code``. + phone_number (str): + Phone number of the business. + + This field is a member of `oneof`_ ``_phone_number``. + """ + + business_name = proto.Field(proto.STRING, number=9, optional=True,) + address_line_1 = proto.Field(proto.STRING, number=10, optional=True,) + address_line_2 = proto.Field(proto.STRING, number=11, optional=True,) + city = proto.Field(proto.STRING, number=12, optional=True,) + province = proto.Field(proto.STRING, number=13, optional=True,) + postal_code = proto.Field(proto.STRING, number=14, optional=True,) + country_code = proto.Field(proto.STRING, number=15, optional=True,) + phone_number = proto.Field(proto.STRING, number=16, optional=True,) + + +class AffiliateLocationFeedItem(proto.Message): + r"""Represents an affiliate location extension. + + Attributes: + business_name (str): + The name of the business. + + This field is a member of `oneof`_ ``_business_name``. + address_line_1 (str): + Line 1 of the business address. + + This field is a member of `oneof`_ ``_address_line_1``. + address_line_2 (str): + Line 2 of the business address. + + This field is a member of `oneof`_ ``_address_line_2``. + city (str): + City of the business address. + + This field is a member of `oneof`_ ``_city``. + province (str): + Province of the business address. + + This field is a member of `oneof`_ ``_province``. + postal_code (str): + Postal code of the business address. + + This field is a member of `oneof`_ ``_postal_code``. + country_code (str): + Country code of the business address. + + This field is a member of `oneof`_ ``_country_code``. + phone_number (str): + Phone number of the business. + + This field is a member of `oneof`_ ``_phone_number``. + chain_id (int): + Id of the retail chain that is advertised as + a seller of your product. + + This field is a member of `oneof`_ ``_chain_id``. + chain_name (str): + Name of chain. + + This field is a member of `oneof`_ ``_chain_name``. + """ + + business_name = proto.Field(proto.STRING, number=11, optional=True,) + address_line_1 = proto.Field(proto.STRING, number=12, optional=True,) + address_line_2 = proto.Field(proto.STRING, number=13, optional=True,) + city = proto.Field(proto.STRING, number=14, optional=True,) + province = proto.Field(proto.STRING, number=15, optional=True,) + postal_code = proto.Field(proto.STRING, number=16, optional=True,) + country_code = proto.Field(proto.STRING, number=17, optional=True,) + phone_number = proto.Field(proto.STRING, number=18, optional=True,) + chain_id = proto.Field(proto.INT64, number=19, optional=True,) + chain_name = proto.Field(proto.STRING, number=20, optional=True,) + + +class TextMessageFeedItem(proto.Message): + r"""An extension that users can click on to send a text message + to the advertiser. + + Attributes: + business_name (str): + The business name to prepend to the message + text. This field is required. + + This field is a member of `oneof`_ ``_business_name``. + country_code (str): + Uppercase two-letter country code of the + advertiser's phone number. This field is + required. + + This field is a member of `oneof`_ ``_country_code``. + phone_number (str): + The advertiser's phone number the message + will be sent to. Required. + + This field is a member of `oneof`_ ``_phone_number``. + text (str): + The text to show in the ad. + This field is required. + + This field is a member of `oneof`_ ``_text``. + extension_text (str): + The message extension_text populated in the messaging app. + + This field is a member of `oneof`_ ``_extension_text``. + """ + + business_name = proto.Field(proto.STRING, number=6, optional=True,) + country_code = proto.Field(proto.STRING, number=7, optional=True,) + phone_number = proto.Field(proto.STRING, number=8, optional=True,) + text = proto.Field(proto.STRING, number=9, optional=True,) + extension_text = proto.Field(proto.STRING, number=10, optional=True,) + + +class PriceFeedItem(proto.Message): + r"""Represents a Price extension. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.PriceExtensionTypeEnum.PriceExtensionType): + Price extension type of this extension. + price_qualifier (google.ads.googleads.v12.enums.types.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier): + Price qualifier for all offers of this price + extension. + tracking_url_template (str): + Tracking URL template for all offers of this + price extension. + + This field is a member of `oneof`_ ``_tracking_url_template``. + language_code (str): + The code of the language used for this price + extension. + + This field is a member of `oneof`_ ``_language_code``. + price_offerings (Sequence[google.ads.googleads.v12.common.types.PriceOffer]): + The price offerings in this price extension. + final_url_suffix (str): + Tracking URL template for all offers of this + price extension. + + This field is a member of `oneof`_ ``_final_url_suffix``. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=price_extension_type.PriceExtensionTypeEnum.PriceExtensionType, + ) + price_qualifier = proto.Field( + proto.ENUM, + number=2, + enum=price_extension_price_qualifier.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier, + ) + tracking_url_template = proto.Field(proto.STRING, number=7, optional=True,) + language_code = proto.Field(proto.STRING, number=8, optional=True,) + price_offerings = proto.RepeatedField( + proto.MESSAGE, number=5, message="PriceOffer", + ) + final_url_suffix = proto.Field(proto.STRING, number=9, optional=True,) + + +class PriceOffer(proto.Message): + r"""Represents one price offer in a price extension. + + Attributes: + header (str): + Header text of this offer. + + This field is a member of `oneof`_ ``_header``. + description (str): + Description text of this offer. + + This field is a member of `oneof`_ ``_description``. + price (google.ads.googleads.v12.common.types.Money): + Price value of this offer. + unit (google.ads.googleads.v12.enums.types.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit): + Price unit for this offer. + final_urls (Sequence[str]): + A list of possible final URLs after all cross + domain redirects. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs after + all cross domain redirects. + """ + + header = proto.Field(proto.STRING, number=7, optional=True,) + description = proto.Field(proto.STRING, number=8, optional=True,) + price = proto.Field(proto.MESSAGE, number=3, message=feed_common.Money,) + unit = proto.Field( + proto.ENUM, + number=4, + enum=price_extension_price_unit.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit, + ) + final_urls = proto.RepeatedField(proto.STRING, number=9,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=10,) + + +class PromotionFeedItem(proto.Message): + r"""Represents a Promotion extension. + + 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: + promotion_target (str): + A freeform description of what the promotion + is targeting. This field is required. + + This field is a member of `oneof`_ ``_promotion_target``. + discount_modifier (google.ads.googleads.v12.enums.types.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier): + Enum that modifies the qualification of the + discount. + promotion_start_date (str): + Start date of when the promotion is eligible + to be redeemed. + + This field is a member of `oneof`_ ``_promotion_start_date``. + promotion_end_date (str): + Last date when the promotion is eligible to + be redeemed. + + This field is a member of `oneof`_ ``_promotion_end_date``. + occasion (google.ads.googleads.v12.enums.types.PromotionExtensionOccasionEnum.PromotionExtensionOccasion): + The occasion the promotion was intended for. + If an occasion is set, the redemption window + will need to fall within the date range + associated with the occasion. + final_urls (Sequence[str]): + A list of possible final URLs after all cross + domain redirects. This field is required. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs after + all cross domain redirects. + tracking_url_template (str): + URL template for constructing a tracking URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + A list of mappings to be used for substituting URL custom + parameter tags in the tracking_url_template, final_urls, + and/or final_mobile_urls. + final_url_suffix (str): + URL template for appending params to landing + page URLs served with parallel tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + language_code (str): + The language of the promotion. + Represented as BCP 47 language tag. + + This field is a member of `oneof`_ ``_language_code``. + percent_off (int): + Percentage off discount in the promotion in micros. One + million is equivalent to one percent. Either this or + money_off_amount is required. + + This field is a member of `oneof`_ ``discount_type``. + money_amount_off (google.ads.googleads.v12.common.types.Money): + Money amount off for discount in the promotion. Either this + or percent_off is required. + + This field is a member of `oneof`_ ``discount_type``. + promotion_code (str): + A code the user should use in order to be + eligible for the promotion. + + This field is a member of `oneof`_ ``promotion_trigger``. + orders_over_amount (google.ads.googleads.v12.common.types.Money): + The amount the total order needs to be for + the user to be eligible for the promotion. + + This field is a member of `oneof`_ ``promotion_trigger``. + """ + + promotion_target = proto.Field(proto.STRING, number=16, optional=True,) + discount_modifier = proto.Field( + proto.ENUM, + number=2, + enum=promotion_extension_discount_modifier.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier, + ) + promotion_start_date = proto.Field(proto.STRING, number=19, optional=True,) + promotion_end_date = proto.Field(proto.STRING, number=20, optional=True,) + occasion = proto.Field( + proto.ENUM, + number=9, + enum=promotion_extension_occasion.PromotionExtensionOccasionEnum.PromotionExtensionOccasion, + ) + final_urls = proto.RepeatedField(proto.STRING, number=21,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=22,) + tracking_url_template = proto.Field(proto.STRING, number=23, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=13, message=custom_parameter.CustomParameter, + ) + final_url_suffix = proto.Field(proto.STRING, number=24, optional=True,) + language_code = proto.Field(proto.STRING, number=25, optional=True,) + percent_off = proto.Field(proto.INT64, number=17, oneof="discount_type",) + money_amount_off = proto.Field( + proto.MESSAGE, + number=4, + oneof="discount_type", + message=feed_common.Money, + ) + promotion_code = proto.Field( + proto.STRING, number=18, oneof="promotion_trigger", + ) + orders_over_amount = proto.Field( + proto.MESSAGE, + number=6, + oneof="promotion_trigger", + message=feed_common.Money, + ) + + +class StructuredSnippetFeedItem(proto.Message): + r"""Represents a structured snippet extension. + + Attributes: + header (str): + The header of the snippet. + This string must not be empty. + + This field is a member of `oneof`_ ``_header``. + values (Sequence[str]): + The values in the snippet. + The maximum size of this collection is 10. + """ + + header = proto.Field(proto.STRING, number=3, optional=True,) + values = proto.RepeatedField(proto.STRING, number=4,) + + +class SitelinkFeedItem(proto.Message): + r"""Represents a sitelink extension. + + Attributes: + link_text (str): + URL display text for the sitelink. + The length of this string should be between 1 + and 25, inclusive. + + This field is a member of `oneof`_ ``_link_text``. + line1 (str): + First line of the description for the + sitelink. If this value is set, line2 must also + be set. The length of this string should be + between 0 and 35, inclusive. + + This field is a member of `oneof`_ ``_line1``. + line2 (str): + Second line of the description for the + sitelink. If this value is set, line1 must also + be set. The length of this string should be + between 0 and 35, inclusive. + + This field is a member of `oneof`_ ``_line2``. + final_urls (Sequence[str]): + A list of possible final URLs after all cross + domain redirects. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs after + all cross domain redirects. + tracking_url_template (str): + URL template for constructing a tracking URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + A list of mappings to be used for substituting URL custom + parameter tags in the tracking_url_template, final_urls, + and/or final_mobile_urls. + final_url_suffix (str): + Final URL suffix to be appended to landing + page URLs served with parallel tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + """ + + link_text = proto.Field(proto.STRING, number=9, optional=True,) + line1 = proto.Field(proto.STRING, number=10, optional=True,) + line2 = proto.Field(proto.STRING, number=11, optional=True,) + final_urls = proto.RepeatedField(proto.STRING, number=12,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=13,) + tracking_url_template = proto.Field(proto.STRING, number=14, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=7, message=custom_parameter.CustomParameter, + ) + final_url_suffix = proto.Field(proto.STRING, number=15, optional=True,) + + +class HotelCalloutFeedItem(proto.Message): + r"""Represents a hotel callout extension. + + Attributes: + text (str): + The callout text. + The length of this string should be between 1 + and 25, inclusive. + + This field is a member of `oneof`_ ``_text``. + language_code (str): + The language of the hotel callout text. + IETF BCP 47 compliant language code. + + This field is a member of `oneof`_ ``_language_code``. + """ + + text = proto.Field(proto.STRING, number=3, optional=True,) + language_code = proto.Field(proto.STRING, number=4, optional=True,) + + +class ImageFeedItem(proto.Message): + r"""Represents an advertiser provided image extension. + + Attributes: + image_asset (str): + Required. Resource name of the image asset. + """ + + image_asset = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/feed_common.py b/google/ads/googleads/v12/common/types/feed_common.py new file mode 100644 index 000000000..db4e03c1a --- /dev/null +++ b/google/ads/googleads/v12/common/types/feed_common.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"Money",}, +) + + +class Money(proto.Message): + r"""Represents a price in a particular currency. + + Attributes: + currency_code (str): + Three-character ISO 4217 currency code. + + This field is a member of `oneof`_ ``_currency_code``. + amount_micros (int): + Amount in micros. One million is equivalent + to one unit. + + This field is a member of `oneof`_ ``_amount_micros``. + """ + + currency_code = proto.Field(proto.STRING, number=3, optional=True,) + amount_micros = proto.Field(proto.INT64, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/feed_item_set_filter_type_infos.py b/google/ads/googleads/v12/common/types/feed_item_set_filter_type_infos.py new file mode 100644 index 000000000..3d6b80981 --- /dev/null +++ b/google/ads/googleads/v12/common/types/feed_item_set_filter_type_infos.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + feed_item_set_string_filter_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "DynamicLocationSetFilter", + "BusinessNameFilter", + "DynamicAffiliateLocationSetFilter", + }, +) + + +class DynamicLocationSetFilter(proto.Message): + r"""Represents a filter on locations in a feed item set. + Only applicable if the parent Feed of the FeedItemSet is a + LOCATION feed. + + Attributes: + labels (Sequence[str]): + If multiple labels are set, then only + feeditems marked with all the labels will be + added to the FeedItemSet. + business_name_filter (google.ads.googleads.v12.common.types.BusinessNameFilter): + Business name filter. + """ + + labels = proto.RepeatedField(proto.STRING, number=1,) + business_name_filter = proto.Field( + proto.MESSAGE, number=2, message="BusinessNameFilter", + ) + + +class BusinessNameFilter(proto.Message): + r"""Represents a business name filter on locations in a + FeedItemSet. + + Attributes: + business_name (str): + Business name string to use for filtering. + filter_type (google.ads.googleads.v12.enums.types.FeedItemSetStringFilterTypeEnum.FeedItemSetStringFilterType): + The type of string matching to use when filtering with + business_name. + """ + + business_name = proto.Field(proto.STRING, number=1,) + filter_type = proto.Field( + proto.ENUM, + number=2, + enum=feed_item_set_string_filter_type.FeedItemSetStringFilterTypeEnum.FeedItemSetStringFilterType, + ) + + +class DynamicAffiliateLocationSetFilter(proto.Message): + r"""Represents a filter on affiliate locations in a FeedItemSet. Only + applicable if the parent Feed of the FeedItemSet is an + AFFILIATE_LOCATION feed. + + Attributes: + chain_ids (Sequence[int]): + Used to filter affiliate locations by chain + ids. Only affiliate locations that belong to the + specified chain(s) will be added to the + FeedItemSet. + """ + + chain_ids = proto.RepeatedField(proto.INT64, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/final_app_url.py b/google/ads/googleads/v12/common/types/final_app_url.py new file mode 100644 index 000000000..52a87e747 --- /dev/null +++ b/google/ads/googleads/v12/common/types/final_app_url.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import app_url_operating_system_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"FinalAppUrl",}, +) + + +class FinalAppUrl(proto.Message): + r"""A URL for deep linking into an app for the given operating + system. + + Attributes: + os_type (google.ads.googleads.v12.enums.types.AppUrlOperatingSystemTypeEnum.AppUrlOperatingSystemType): + The operating system targeted by this URL. + Required. + url (str): + The app deep link URL. Deep links specify a location in an + app that corresponds to the content you'd like to show, and + should be of the form {scheme}://{host_path} The scheme + identifies which app to open. For your app, you can use a + custom scheme that starts with the app's name. The host and + path specify the unique location in the app where your + content exists. Example: "exampleapp://productid_1234". + Required. + + This field is a member of `oneof`_ ``_url``. + """ + + os_type = proto.Field( + proto.ENUM, + number=1, + enum=app_url_operating_system_type.AppUrlOperatingSystemTypeEnum.AppUrlOperatingSystemType, + ) + url = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/frequency_cap.py b/google/ads/googleads/v12/common/types/frequency_cap.py new file mode 100644 index 000000000..5ef9f4eaf --- /dev/null +++ b/google/ads/googleads/v12/common/types/frequency_cap.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import frequency_cap_event_type +from google.ads.googleads.v12.enums.types import frequency_cap_level +from google.ads.googleads.v12.enums.types import frequency_cap_time_unit + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"FrequencyCapEntry", "FrequencyCapKey",}, +) + + +class FrequencyCapEntry(proto.Message): + r"""A rule specifying the maximum number of times an ad (or some + set of ads) can be shown to a user over a particular time + period. + + Attributes: + key (google.ads.googleads.v12.common.types.FrequencyCapKey): + The key of a particular frequency cap. There + can be no more than one frequency cap with the + same key. + cap (int): + Maximum number of events allowed during the + time range by this cap. + + This field is a member of `oneof`_ ``_cap``. + """ + + key = proto.Field(proto.MESSAGE, number=1, message="FrequencyCapKey",) + cap = proto.Field(proto.INT32, number=3, optional=True,) + + +class FrequencyCapKey(proto.Message): + r"""A group of fields used as keys for a frequency cap. + There can be no more than one frequency cap with the same key. + + Attributes: + level (google.ads.googleads.v12.enums.types.FrequencyCapLevelEnum.FrequencyCapLevel): + The level on which the cap is to be applied + (for example, ad group ad, ad group). The cap is + applied to all the entities of this level. + event_type (google.ads.googleads.v12.enums.types.FrequencyCapEventTypeEnum.FrequencyCapEventType): + The type of event that the cap applies to + (for example, impression). + time_unit (google.ads.googleads.v12.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): + Unit of time the cap is defined at (for + example, day, week). + time_length (int): + Number of time units the cap lasts. + + This field is a member of `oneof`_ ``_time_length``. + """ + + level = proto.Field( + proto.ENUM, + number=1, + enum=frequency_cap_level.FrequencyCapLevelEnum.FrequencyCapLevel, + ) + event_type = proto.Field( + proto.ENUM, + number=3, + enum=frequency_cap_event_type.FrequencyCapEventTypeEnum.FrequencyCapEventType, + ) + time_unit = proto.Field( + proto.ENUM, + number=2, + enum=frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit, + ) + time_length = proto.Field(proto.INT32, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/keyword_plan_common.py b/google/ads/googleads/v12/common/types/keyword_plan_common.py new file mode 100644 index 000000000..92e6d58d0 --- /dev/null +++ b/google/ads/googleads/v12/common/types/keyword_plan_common.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import dates +from google.ads.googleads.v12.enums.types import device as gage_device +from google.ads.googleads.v12.enums.types import ( + keyword_plan_aggregate_metric_type, +) +from google.ads.googleads.v12.enums.types import keyword_plan_competition_level +from google.ads.googleads.v12.enums.types import keyword_plan_concept_group_type +from google.ads.googleads.v12.enums.types import month_of_year + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "KeywordPlanHistoricalMetrics", + "HistoricalMetricsOptions", + "MonthlySearchVolume", + "KeywordPlanAggregateMetrics", + "KeywordPlanAggregateMetricResults", + "KeywordPlanDeviceSearches", + "KeywordAnnotations", + "KeywordConcept", + "ConceptGroup", + }, +) + + +class KeywordPlanHistoricalMetrics(proto.Message): + r"""Historical metrics specific to the targeting options + selected. Targeting options include geographies, network, etc. + Refer to https://support.google.com/google-ads/answer/3022575 + for more details. + + Attributes: + avg_monthly_searches (int): + Approximate number of monthly searches on + this query averaged for the past 12 months. + + This field is a member of `oneof`_ ``_avg_monthly_searches``. + monthly_search_volumes (Sequence[google.ads.googleads.v12.common.types.MonthlySearchVolume]): + Approximate number of searches on this query + for the past twelve months. + competition (google.ads.googleads.v12.enums.types.KeywordPlanCompetitionLevelEnum.KeywordPlanCompetitionLevel): + The competition level for the query. + competition_index (int): + The competition index for the query in the range [0, 100]. + Shows how competitive ad placement is for a keyword. The + level of competition from 0-100 is determined by the number + of ad slots filled divided by the total number of ad slots + available. If not enough data is available, null is + returned. + + This field is a member of `oneof`_ ``_competition_index``. + low_top_of_page_bid_micros (int): + Top of page bid low range (20th percentile) + in micros for the keyword. + + This field is a member of `oneof`_ ``_low_top_of_page_bid_micros``. + high_top_of_page_bid_micros (int): + Top of page bid high range (80th percentile) + in micros for the keyword. + + This field is a member of `oneof`_ ``_high_top_of_page_bid_micros``. + average_cpc_micros (int): + Average Cost Per Click in micros for the + keyword. + + This field is a member of `oneof`_ ``_average_cpc_micros``. + """ + + avg_monthly_searches = proto.Field(proto.INT64, number=7, optional=True,) + monthly_search_volumes = proto.RepeatedField( + proto.MESSAGE, number=6, message="MonthlySearchVolume", + ) + competition = proto.Field( + proto.ENUM, + number=2, + enum=keyword_plan_competition_level.KeywordPlanCompetitionLevelEnum.KeywordPlanCompetitionLevel, + ) + competition_index = proto.Field(proto.INT64, number=8, optional=True,) + low_top_of_page_bid_micros = proto.Field( + proto.INT64, number=9, optional=True, + ) + high_top_of_page_bid_micros = proto.Field( + proto.INT64, number=10, optional=True, + ) + average_cpc_micros = proto.Field(proto.INT64, number=11, optional=True,) + + +class HistoricalMetricsOptions(proto.Message): + r"""Historical metrics options. + + Attributes: + year_month_range (google.ads.googleads.v12.common.types.YearMonthRange): + The year month range for historical metrics. If not + specified the searches will be returned for past 12 months. + Searches data is available for the past 4 years. If the + search volume is not available for the entire + year_month_range provided, the subset of the year month + range for which search volume is available will be returned. + + This field is a member of `oneof`_ ``_year_month_range``. + include_average_cpc (bool): + Indicates whether to include average cost per + click value. Average CPC is a legacy value that + will be removed and replaced in the future, and + as such we are including it as an optioanl value + so clients only use it when strictly necessary + and to better track clients that use this value. + """ + + year_month_range = proto.Field( + proto.MESSAGE, number=1, optional=True, message=dates.YearMonthRange, + ) + include_average_cpc = proto.Field(proto.BOOL, number=2,) + + +class MonthlySearchVolume(proto.Message): + r"""Monthly search volume. + + Attributes: + year (int): + The year of the search volume (for example, + 2020). + + This field is a member of `oneof`_ ``_year``. + month (google.ads.googleads.v12.enums.types.MonthOfYearEnum.MonthOfYear): + The month of the search volume. + monthly_searches (int): + Approximate number of searches for the month. + A null value indicates the search volume is + unavailable for that month. + + This field is a member of `oneof`_ ``_monthly_searches``. + """ + + year = proto.Field(proto.INT64, number=4, optional=True,) + month = proto.Field( + proto.ENUM, number=2, enum=month_of_year.MonthOfYearEnum.MonthOfYear, + ) + monthly_searches = proto.Field(proto.INT64, number=5, optional=True,) + + +class KeywordPlanAggregateMetrics(proto.Message): + r"""The aggregate metrics specification of the request. + + Attributes: + aggregate_metric_types (Sequence[google.ads.googleads.v12.enums.types.KeywordPlanAggregateMetricTypeEnum.KeywordPlanAggregateMetricType]): + The list of aggregate metrics to fetch data. + """ + + aggregate_metric_types = proto.RepeatedField( + proto.ENUM, + number=1, + enum=keyword_plan_aggregate_metric_type.KeywordPlanAggregateMetricTypeEnum.KeywordPlanAggregateMetricType, + ) + + +class KeywordPlanAggregateMetricResults(proto.Message): + r"""The aggregated historical metrics for keyword plan keywords. + + Attributes: + device_searches (Sequence[google.ads.googleads.v12.common.types.KeywordPlanDeviceSearches]): + The aggregate searches for all the keywords + segmented by device for the specified time. + Supports the following device types: MOBILE, + TABLET, DESKTOP. + This is only set when + KeywordPlanAggregateMetricTypeEnum.DEVICE is set + in the KeywordPlanAggregateMetrics field in the + request. + """ + + device_searches = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanDeviceSearches", + ) + + +class KeywordPlanDeviceSearches(proto.Message): + r"""The total searches for the device type during the specified + time period. + + Attributes: + device (google.ads.googleads.v12.enums.types.DeviceEnum.Device): + The device type. + search_count (int): + The total searches for the device. + + This field is a member of `oneof`_ ``_search_count``. + """ + + device = proto.Field( + proto.ENUM, number=1, enum=gage_device.DeviceEnum.Device, + ) + search_count = proto.Field(proto.INT64, number=2, optional=True,) + + +class KeywordAnnotations(proto.Message): + r"""The Annotations for the Keyword plan keywords. + + Attributes: + concepts (Sequence[google.ads.googleads.v12.common.types.KeywordConcept]): + The list of concepts for the keyword. + """ + + concepts = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordConcept", + ) + + +class KeywordConcept(proto.Message): + r"""The concept for the keyword. + + Attributes: + name (str): + The concept name for the keyword in the concept_group. + concept_group (google.ads.googleads.v12.common.types.ConceptGroup): + The concept group of the concept details. + """ + + name = proto.Field(proto.STRING, number=1,) + concept_group = proto.Field( + proto.MESSAGE, number=2, message="ConceptGroup", + ) + + +class ConceptGroup(proto.Message): + r"""The concept group for the keyword concept. + + Attributes: + name (str): + The concept group name. + type_ (google.ads.googleads.v12.enums.types.KeywordPlanConceptGroupTypeEnum.KeywordPlanConceptGroupType): + The concept group type. + """ + + name = proto.Field(proto.STRING, number=1,) + type_ = proto.Field( + proto.ENUM, + number=2, + enum=keyword_plan_concept_group_type.KeywordPlanConceptGroupTypeEnum.KeywordPlanConceptGroupType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/matching_function.py b/google/ads/googleads/v12/common/types/matching_function.py new file mode 100644 index 000000000..e72f21dd0 --- /dev/null +++ b/google/ads/googleads/v12/common/types/matching_function.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import matching_function_context_type +from google.ads.googleads.v12.enums.types import matching_function_operator + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"MatchingFunction", "Operand",}, +) + + +class MatchingFunction(proto.Message): + r"""Matching function associated with a + CustomerFeed, CampaignFeed, or AdGroupFeed. The matching + function is used to filter the set of feed items selected. + + Attributes: + function_string (str): + String representation of the Function. + + Examples: + + 1. IDENTITY(true) or IDENTITY(false). All or no feed items + served. + 2. EQUALS(CONTEXT.DEVICE,"Mobile") + 3. IN(FEED_ITEM_ID,{1000001,1000002,1000003}) + 4. CONTAINS_ANY(FeedAttribute[12345678,0],{"Mars + cruise","Venus cruise"}) + 5. AND(IN(FEED_ITEM_ID,{10001,10002}),EQUALS(CONTEXT.DEVICE,"Mobile")) + + For more details, visit + https://developers.google.com/adwords/api/docs/guides/feed-matching-functions + + Note that because multiple strings may represent the same + underlying function (whitespace and single versus double + quotation marks, for example), the value returned may not be + identical to the string sent in a mutate request. + + This field is a member of `oneof`_ ``_function_string``. + operator (google.ads.googleads.v12.enums.types.MatchingFunctionOperatorEnum.MatchingFunctionOperator): + Operator for a function. + left_operands (Sequence[google.ads.googleads.v12.common.types.Operand]): + The operands on the left hand side of the + equation. This is also the operand to be used + for single operand expressions such as NOT. + right_operands (Sequence[google.ads.googleads.v12.common.types.Operand]): + The operands on the right hand side of the + equation. + """ + + function_string = proto.Field(proto.STRING, number=5, optional=True,) + operator = proto.Field( + proto.ENUM, + number=4, + enum=matching_function_operator.MatchingFunctionOperatorEnum.MatchingFunctionOperator, + ) + left_operands = proto.RepeatedField( + proto.MESSAGE, number=2, message="Operand", + ) + right_operands = proto.RepeatedField( + proto.MESSAGE, number=3, message="Operand", + ) + + +class Operand(proto.Message): + r"""An operand in a matching function. + + 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: + constant_operand (google.ads.googleads.v12.common.types.Operand.ConstantOperand): + A constant operand in a matching function. + + This field is a member of `oneof`_ ``function_argument_operand``. + feed_attribute_operand (google.ads.googleads.v12.common.types.Operand.FeedAttributeOperand): + This operand specifies a feed attribute in + feed. + + This field is a member of `oneof`_ ``function_argument_operand``. + function_operand (google.ads.googleads.v12.common.types.Operand.FunctionOperand): + A function operand in a matching function. + Used to represent nested functions. + + This field is a member of `oneof`_ ``function_argument_operand``. + request_context_operand (google.ads.googleads.v12.common.types.Operand.RequestContextOperand): + An operand in a function referring to a value + in the request context. + + This field is a member of `oneof`_ ``function_argument_operand``. + """ + + class ConstantOperand(proto.Message): + r"""A constant operand in a matching function. + + 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: + string_value (str): + String value of the operand if it is a string + type. + + This field is a member of `oneof`_ ``constant_operand_value``. + long_value (int): + Int64 value of the operand if it is a int64 + type. + + This field is a member of `oneof`_ ``constant_operand_value``. + boolean_value (bool): + Boolean value of the operand if it is a + boolean type. + + This field is a member of `oneof`_ ``constant_operand_value``. + double_value (float): + Double value of the operand if it is a double + type. + + This field is a member of `oneof`_ ``constant_operand_value``. + """ + + string_value = proto.Field( + proto.STRING, number=5, oneof="constant_operand_value", + ) + long_value = proto.Field( + proto.INT64, number=6, oneof="constant_operand_value", + ) + boolean_value = proto.Field( + proto.BOOL, number=7, oneof="constant_operand_value", + ) + double_value = proto.Field( + proto.DOUBLE, number=8, oneof="constant_operand_value", + ) + + class FeedAttributeOperand(proto.Message): + r"""A feed attribute operand in a matching function. + Used to represent a feed attribute in feed. + + Attributes: + feed_id (int): + The associated feed. Required. + + This field is a member of `oneof`_ ``_feed_id``. + feed_attribute_id (int): + Id of the referenced feed attribute. + Required. + + This field is a member of `oneof`_ ``_feed_attribute_id``. + """ + + feed_id = proto.Field(proto.INT64, number=3, optional=True,) + feed_attribute_id = proto.Field(proto.INT64, number=4, optional=True,) + + class FunctionOperand(proto.Message): + r"""A function operand in a matching function. + Used to represent nested functions. + + Attributes: + matching_function (google.ads.googleads.v12.common.types.MatchingFunction): + The matching function held in this operand. + """ + + matching_function = proto.Field( + proto.MESSAGE, number=1, message="MatchingFunction", + ) + + class RequestContextOperand(proto.Message): + r"""An operand in a function referring to a value in the request + context. + + Attributes: + context_type (google.ads.googleads.v12.enums.types.MatchingFunctionContextTypeEnum.MatchingFunctionContextType): + Type of value to be referred in the request + context. + """ + + context_type = proto.Field( + proto.ENUM, + number=1, + enum=matching_function_context_type.MatchingFunctionContextTypeEnum.MatchingFunctionContextType, + ) + + constant_operand = proto.Field( + proto.MESSAGE, + number=1, + oneof="function_argument_operand", + message=ConstantOperand, + ) + feed_attribute_operand = proto.Field( + proto.MESSAGE, + number=2, + oneof="function_argument_operand", + message=FeedAttributeOperand, + ) + function_operand = proto.Field( + proto.MESSAGE, + number=3, + oneof="function_argument_operand", + message=FunctionOperand, + ) + request_context_operand = proto.Field( + proto.MESSAGE, + number=4, + oneof="function_argument_operand", + message=RequestContextOperand, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/metric_goal.py b/google/ads/googleads/v12/common/types/metric_goal.py new file mode 100644 index 000000000..d971f516e --- /dev/null +++ b/google/ads/googleads/v12/common/types/metric_goal.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import experiment_metric +from google.ads.googleads.v12.enums.types import experiment_metric_direction + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"MetricGoal",}, +) + + +class MetricGoal(proto.Message): + r"""A metric goal for an experiment. + + Attributes: + metric (google.ads.googleads.v12.enums.types.ExperimentMetricEnum.ExperimentMetric): + The metric of the goal. For example, clicks, + impressions, cost, conversions, etc. + direction (google.ads.googleads.v12.enums.types.ExperimentMetricDirectionEnum.ExperimentMetricDirection): + The metric direction of the goal. For + example, increase, decrease, no change. + """ + + metric = proto.Field( + proto.ENUM, + number=1, + enum=experiment_metric.ExperimentMetricEnum.ExperimentMetric, + ) + direction = proto.Field( + proto.ENUM, + number=2, + enum=experiment_metric_direction.ExperimentMetricDirectionEnum.ExperimentMetricDirection, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/metrics.py b/google/ads/googleads/v12/common/types/metrics.py new file mode 100644 index 000000000..24c9b00fd --- /dev/null +++ b/google/ads/googleads/v12/common/types/metrics.py @@ -0,0 +1,1389 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import interaction_event_type +from google.ads.googleads.v12.enums.types import quality_score_bucket + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"Metrics",}, +) + + +class Metrics(proto.Message): + r"""Metrics data. + + Attributes: + absolute_top_impression_percentage (float): + The percent of your ad impressions that are + shown as the very first ad above the organic + search results. + + This field is a member of `oneof`_ ``_absolute_top_impression_percentage``. + active_view_cpm (float): + Average cost of viewable impressions + (``active_view_impressions``). + + This field is a member of `oneof`_ ``_active_view_cpm``. + active_view_ctr (float): + Active view measurable clicks divided by + active view viewable impressions. This metric is + reported only for display network. + + This field is a member of `oneof`_ ``_active_view_ctr``. + active_view_impressions (int): + A measurement of how often your ad has become + viewable on a Display Network site. + + This field is a member of `oneof`_ ``_active_view_impressions``. + active_view_measurability (float): + The ratio of impressions that could be + measured by Active View over the number of + served impressions. + + This field is a member of `oneof`_ ``_active_view_measurability``. + active_view_measurable_cost_micros (int): + The cost of the impressions you received that + were measurable by Active View. + + This field is a member of `oneof`_ ``_active_view_measurable_cost_micros``. + active_view_measurable_impressions (int): + The number of times your ads are appearing on + placements in positions where they can be seen. + + This field is a member of `oneof`_ ``_active_view_measurable_impressions``. + active_view_viewability (float): + The percentage of time when your ad appeared + on an Active View enabled site (measurable + impressions) and was viewable (viewable + impressions). + + This field is a member of `oneof`_ ``_active_view_viewability``. + all_conversions_from_interactions_rate (float): + All conversions from interactions (as oppose + to view through conversions) divided by the + number of ad interactions. + + This field is a member of `oneof`_ ``_all_conversions_from_interactions_rate``. + all_conversions_value (float): + The value of all conversions. + + This field is a member of `oneof`_ ``_all_conversions_value``. + all_conversions_value_by_conversion_date (float): + The value of all conversions. When this column is selected + with date, the values in date column means the conversion + date. Details for the by_conversion_date columns are + available at + https://support.google.com/google-ads/answer/9549009. + all_conversions (float): + The total number of conversions. This includes all + conversions regardless of the value of + include_in_conversions_metric. + + This field is a member of `oneof`_ ``_all_conversions``. + all_conversions_by_conversion_date (float): + The total number of conversions. This includes all + conversions regardless of the value of + include_in_conversions_metric. When this column is selected + with date, the values in date column means the conversion + date. Details for the by_conversion_date columns are + available at + https://support.google.com/google-ads/answer/9549009. + all_conversions_value_per_cost (float): + The value of all conversions divided by the + total cost of ad interactions (such as clicks + for text ads or views for video ads). + + This field is a member of `oneof`_ ``_all_conversions_value_per_cost``. + all_conversions_from_click_to_call (float): + The number of times people clicked the "Call" + button to call a store during or after clicking + an ad. This number doesn't include whether or + not calls were connected, or the duration of any + calls. This metric applies to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_click_to_call``. + all_conversions_from_directions (float): + The number of times people clicked a "Get + directions" button to navigate to a store after + clicking an ad. This metric applies to feed + items only. + + This field is a member of `oneof`_ ``_all_conversions_from_directions``. + all_conversions_from_interactions_value_per_interaction (float): + The value of all conversions from + interactions divided by the total number of + interactions. + + This field is a member of `oneof`_ ``_all_conversions_from_interactions_value_per_interaction``. + all_conversions_from_menu (float): + The number of times people clicked a link to + view a store's menu after clicking an ad. + This metric applies to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_menu``. + all_conversions_from_order (float): + The number of times people placed an order at + a store after clicking an ad. This metric + applies to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_order``. + all_conversions_from_other_engagement (float): + The number of other conversions (for example, + posting a review or saving a location for a + store) that occurred after people clicked an ad. + This metric applies to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_other_engagement``. + all_conversions_from_store_visit (float): + Estimated number of times people visited a + store after clicking an ad. This metric applies + to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_store_visit``. + all_conversions_from_store_website (float): + The number of times that people were taken to + a store's URL after clicking an ad. + This metric applies to feed items only. + + This field is a member of `oneof`_ ``_all_conversions_from_store_website``. + auction_insight_search_absolute_top_impression_percentage (float): + This metric is part of the Auction Insights + report, and tells how often the ads of another + participant showed as the very first ad above + the organic search results. + This percentage is computed only over the + auctions that you appeared in the page. + This metric is not publicly available. + + This field is a member of `oneof`_ ``_auction_insight_search_absolute_top_impression_percentage``. + auction_insight_search_impression_share (float): + This metric is part of the Auction Insights + report, and tells the percentage of impressions + that another participant obtained, over the + total number of impressions that your ads were + eligible for. Any value below 0.1 is reported as + 0.0999. + This metric is not publicly available. + + This field is a member of `oneof`_ ``_auction_insight_search_impression_share``. + auction_insight_search_outranking_share (float): + This metric is part of the Auction Insights + report, and tells the percentage of impressions + that your ads outranked (showed above) another + participant in the auction, compared to the + total number of impressions that your ads were + eligible for. + Any value below 0.1 is reported as 0.0999. + This metric is not publicly available. + + This field is a member of `oneof`_ ``_auction_insight_search_outranking_share``. + auction_insight_search_overlap_rate (float): + This metric is part of the Auction Insights + report, and tells how often another + participant's ad received an impression when + your ad also received an impression. + This metric is not publicly available. + + This field is a member of `oneof`_ ``_auction_insight_search_overlap_rate``. + auction_insight_search_position_above_rate (float): + This metric is part of the Auction Insights + report, and tells how often another + participant's ad was shown in a higher position + than yours, when both of your ads were shown at + the same page. This metric is not publicly + available. + + This field is a member of `oneof`_ ``_auction_insight_search_position_above_rate``. + auction_insight_search_top_impression_percentage (float): + This metric is part of the Auction Insights + report, and tells how often the ads of another + participant showed above the organic search + results. This percentage is computed only over + the auctions that you appeared in the page. + This metric is not publicly available. + + This field is a member of `oneof`_ ``_auction_insight_search_top_impression_percentage``. + average_cost (float): + The average amount you pay per interaction. + This amount is the total cost of your ads + divided by the total number of interactions. + + This field is a member of `oneof`_ ``_average_cost``. + average_cpc (float): + The total cost of all clicks divided by the + total number of clicks received. + + This field is a member of `oneof`_ ``_average_cpc``. + average_cpe (float): + The average amount that you've been charged + for an ad engagement. This amount is the total + cost of all ad engagements divided by the total + number of ad engagements. + + This field is a member of `oneof`_ ``_average_cpe``. + average_cpm (float): + Average cost-per-thousand impressions (CPM). + + This field is a member of `oneof`_ ``_average_cpm``. + average_cpv (float): + The average amount you pay each time someone + views your ad. The average CPV is defined by the + total cost of all ad views divided by the number + of views. + + This field is a member of `oneof`_ ``_average_cpv``. + average_page_views (float): + Average number of pages viewed per session. + + This field is a member of `oneof`_ ``_average_page_views``. + average_time_on_site (float): + Total duration of all sessions (in seconds) / + number of sessions. Imported from Google + Analytics. + + This field is a member of `oneof`_ ``_average_time_on_site``. + benchmark_average_max_cpc (float): + An indication of how other advertisers are + bidding on similar products. + + This field is a member of `oneof`_ ``_benchmark_average_max_cpc``. + biddable_app_install_conversions (float): + Number of app installs. + + This field is a member of `oneof`_ ``_biddable_app_install_conversions``. + biddable_app_post_install_conversions (float): + Number of in-app actions. + + This field is a member of `oneof`_ ``_biddable_app_post_install_conversions``. + benchmark_ctr (float): + An indication on how other advertisers' + Shopping ads for similar products are performing + based on how often people who see their ad click + on it. + + This field is a member of `oneof`_ ``_benchmark_ctr``. + bounce_rate (float): + Percentage of clicks where the user only + visited a single page on your site. Imported + from Google Analytics. + + This field is a member of `oneof`_ ``_bounce_rate``. + clicks (int): + The number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + combined_clicks (int): + The number of times your ad or your site's + listing in the unpaid results was clicked. See + the help page at + https://support.google.com/google-ads/answer/3097241 + for details. + + This field is a member of `oneof`_ ``_combined_clicks``. + combined_clicks_per_query (float): + The number of times your ad or your site's listing in the + unpaid results was clicked (combined_clicks) divided by + combined_queries. See the help page at + https://support.google.com/google-ads/answer/3097241 for + details. + + This field is a member of `oneof`_ ``_combined_clicks_per_query``. + combined_queries (int): + The number of searches that returned pages + from your site in the unpaid results or showed + one of your text ads. See the help page at + https://support.google.com/google-ads/answer/3097241 + for details. + + This field is a member of `oneof`_ ``_combined_queries``. + content_budget_lost_impression_share (float): + The estimated percent of times that your ad + was eligible to show on the Display Network but + didn't because your budget was too low. Note: + Content budget lost impression share is reported + in the range of 0 to 0.9. Any value above 0.9 is + reported as 0.9001. + + This field is a member of `oneof`_ ``_content_budget_lost_impression_share``. + content_impression_share (float): + The impressions you've received on the + Display Network divided by the estimated number + of impressions you were eligible to receive. + Note: Content impression share is reported in + the range of 0.1 to 1. Any value below 0.1 is + reported as 0.0999. + + This field is a member of `oneof`_ ``_content_impression_share``. + conversion_last_received_request_date_time (str): + The last date/time a conversion tag for this + conversion action successfully fired and was + seen by Google Ads. This firing event may not + have been the result of an attributable + conversion (for example, because the tag was + fired from a browser that did not previously + click an ad from an appropriate advertiser). The + date/time is in the customer's time zone. + + This field is a member of `oneof`_ ``_conversion_last_received_request_date_time``. + conversion_last_conversion_date (str): + The date of the most recent conversion for + this conversion action. The date is in the + customer's time zone. + + This field is a member of `oneof`_ ``_conversion_last_conversion_date``. + content_rank_lost_impression_share (float): + The estimated percentage of impressions on + the Display Network that your ads didn't receive + due to poor Ad Rank. Note: Content rank lost + impression share is reported in the range of 0 + to 0.9. Any value above 0.9 is reported as + 0.9001. + + This field is a member of `oneof`_ ``_content_rank_lost_impression_share``. + conversions_from_interactions_rate (float): + Conversions from interactions divided by the number of ad + interactions (such as clicks for text ads or views for video + ads). This only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_conversions_from_interactions_rate``. + conversions_value (float): + The value of conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_conversions_value``. + conversions_value_by_conversion_date (float): + The value of conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. When this + column is selected with date, the values in date column + means the conversion date. Details for the + by_conversion_date columns are available at + https://support.google.com/google-ads/answer/9549009. + conversions_value_per_cost (float): + The value of conversions divided by the cost of ad + interactions. This only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_conversions_value_per_cost``. + conversions_from_interactions_value_per_interaction (float): + The value of conversions from interactions divided by the + number of ad interactions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_conversions_from_interactions_value_per_interaction``. + conversions (float): + The number of conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_conversions``. + conversions_by_conversion_date (float): + The number of conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. When this + column is selected with date, the values in date column + means the conversion date. Details for the + by_conversion_date columns are available at + https://support.google.com/google-ads/answer/9549009. + cost_micros (int): + The sum of your cost-per-click (CPC) and + cost-per-thousand impressions (CPM) costs during + this period. + + This field is a member of `oneof`_ ``_cost_micros``. + cost_per_all_conversions (float): + The cost of ad interactions divided by all + conversions. + + This field is a member of `oneof`_ ``_cost_per_all_conversions``. + cost_per_conversion (float): + The cost of ad interactions divided by conversions. This + only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_cost_per_conversion``. + cost_per_current_model_attributed_conversion (float): + The cost of ad interactions divided by current model + attributed conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_cost_per_current_model_attributed_conversion``. + cross_device_conversions (float): + Conversions from when a customer clicks on a Google Ads ad + on one device, then converts on a different device or + browser. Cross-device conversions are already included in + all_conversions. + + This field is a member of `oneof`_ ``_cross_device_conversions``. + ctr (float): + The number of clicks your ad receives + (Clicks) divided by the number of times your ad + is shown (Impressions). + + This field is a member of `oneof`_ ``_ctr``. + current_model_attributed_conversions (float): + Shows how your historic conversions data would look under + the attribution model you've currently selected. This only + includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_current_model_attributed_conversions``. + current_model_attributed_conversions_from_interactions_rate (float): + Current model attributed conversions from interactions + divided by the number of ad interactions (such as clicks for + text ads or views for video ads). This only includes + conversion actions which include_in_conversions_metric + attribute is set to true. If you use conversion-based + bidding, your bid strategies will optimize for these + conversions. + + This field is a member of `oneof`_ ``_current_model_attributed_conversions_from_interactions_rate``. + current_model_attributed_conversions_from_interactions_value_per_interaction (float): + The value of current model attributed conversions from + interactions divided by the number of ad interactions. This + only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_current_model_attributed_conversions_from_interactions_value_per_interaction``. + current_model_attributed_conversions_value (float): + The value of current model attributed conversions. This only + includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_current_model_attributed_conversions_value``. + current_model_attributed_conversions_value_per_cost (float): + The value of current model attributed conversions divided by + the cost of ad interactions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_current_model_attributed_conversions_value_per_cost``. + engagement_rate (float): + How often people engage with your ad after + it's shown to them. This is the number of ad + expansions divided by the number of times your + ad is shown. + + This field is a member of `oneof`_ ``_engagement_rate``. + engagements (int): + The number of engagements. + An engagement occurs when a viewer expands your + Lightbox ad. Also, in the future, other ad types + may support engagement metrics. + + This field is a member of `oneof`_ ``_engagements``. + hotel_average_lead_value_micros (float): + Average lead value based on clicks. + + This field is a member of `oneof`_ ``_hotel_average_lead_value_micros``. + hotel_commission_rate_micros (int): + Commission bid rate in micros. A 20% + commission is represented as 200,000. + + This field is a member of `oneof`_ ``_hotel_commission_rate_micros``. + hotel_expected_commission_cost (float): + Expected commission cost. The result of multiplying the + commission value times the hotel_commission_rate in + advertiser currency. + + This field is a member of `oneof`_ ``_hotel_expected_commission_cost``. + hotel_price_difference_percentage (float): + The average price difference between the + price offered by reporting hotel advertiser and + the cheapest price offered by the competing + advertiser. + + This field is a member of `oneof`_ ``_hotel_price_difference_percentage``. + hotel_eligible_impressions (int): + The number of impressions that hotel partners + could have had given their feed performance. + + This field is a member of `oneof`_ ``_hotel_eligible_impressions``. + historical_creative_quality_score (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + The creative historical quality score. + historical_landing_page_quality_score (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + The quality of historical landing page + experience. + historical_quality_score (int): + The historical quality score. + + This field is a member of `oneof`_ ``_historical_quality_score``. + historical_search_predicted_ctr (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + The historical search predicted click through + rate (CTR). + gmail_forwards (int): + The number of times the ad was forwarded to + someone else as a message. + + This field is a member of `oneof`_ ``_gmail_forwards``. + gmail_saves (int): + The number of times someone has saved your + Gmail ad to their inbox as a message. + + This field is a member of `oneof`_ ``_gmail_saves``. + gmail_secondary_clicks (int): + The number of clicks to the landing page on + the expanded state of Gmail ads. + + This field is a member of `oneof`_ ``_gmail_secondary_clicks``. + impressions_from_store_reach (int): + The number of times a store's location-based + ad was shown. This metric applies to feed items + only. + + This field is a member of `oneof`_ ``_impressions_from_store_reach``. + impressions (int): + Count of how often your ad has appeared on a + search results page or website on the Google + Network. + + This field is a member of `oneof`_ ``_impressions``. + interaction_rate (float): + How often people interact with your ad after + it is shown to them. This is the number of + interactions divided by the number of times your + ad is shown. + + This field is a member of `oneof`_ ``_interaction_rate``. + interactions (int): + The number of interactions. + An interaction is the main user action + associated with an ad format-clicks for text and + shopping ads, views for video ads, and so on. + + This field is a member of `oneof`_ ``_interactions``. + interaction_event_types (Sequence[google.ads.googleads.v12.enums.types.InteractionEventTypeEnum.InteractionEventType]): + The types of payable and free interactions. + invalid_click_rate (float): + The percentage of clicks filtered out of your + total number of clicks (filtered + non-filtered + clicks) during the reporting period. + + This field is a member of `oneof`_ ``_invalid_click_rate``. + invalid_clicks (int): + Number of clicks Google considers + illegitimate and doesn't charge you for. + + This field is a member of `oneof`_ ``_invalid_clicks``. + message_chats (int): + Number of message chats initiated for Click + To Message impressions that were message + tracking eligible. + + This field is a member of `oneof`_ ``_message_chats``. + message_impressions (int): + Number of Click To Message impressions that + were message tracking eligible. + + This field is a member of `oneof`_ ``_message_impressions``. + message_chat_rate (float): + Number of message chats initiated (message_chats) divided by + the number of message impressions (message_impressions). + Rate at which a user initiates a message chat from an ad + impression with a messaging option and message tracking + enabled. Note that this rate can be more than 1.0 for a + given message impression. + + This field is a member of `oneof`_ ``_message_chat_rate``. + mobile_friendly_clicks_percentage (float): + The percentage of mobile clicks that go to a + mobile-friendly page. + + This field is a member of `oneof`_ ``_mobile_friendly_clicks_percentage``. + optimization_score_uplift (float): + Total optimization score uplift of all + recommendations. + + This field is a member of `oneof`_ ``_optimization_score_uplift``. + optimization_score_url (str): + URL for the optimization score page in the Google Ads web + interface. This metric can be selected from ``customer`` or + ``campaign``, and can be segmented by + ``segments.recommendation_type``. For example, + ``SELECT metrics.optimization_score_url, segments.recommendation_type FROM customer`` + will return a URL for each unique (customer, + recommendation_type) combination. + + This field is a member of `oneof`_ ``_optimization_score_url``. + organic_clicks (int): + The number of times someone clicked your + site's listing in the unpaid results for a + particular query. See the help page at + https://support.google.com/google-ads/answer/3097241 + for details. + + This field is a member of `oneof`_ ``_organic_clicks``. + organic_clicks_per_query (float): + The number of times someone clicked your site's listing in + the unpaid results (organic_clicks) divided by the total + number of searches that returned pages from your site + (organic_queries). See the help page at + https://support.google.com/google-ads/answer/3097241 for + details. + + This field is a member of `oneof`_ ``_organic_clicks_per_query``. + organic_impressions (int): + The number of listings for your site in the + unpaid search results. See the help page at + https://support.google.com/google-ads/answer/3097241 + for details. + + This field is a member of `oneof`_ ``_organic_impressions``. + organic_impressions_per_query (float): + The number of times a page from your site was listed in the + unpaid search results (organic_impressions) divided by the + number of searches returning your site's listing in the + unpaid results (organic_queries). See the help page at + https://support.google.com/google-ads/answer/3097241 for + details. + + This field is a member of `oneof`_ ``_organic_impressions_per_query``. + organic_queries (int): + The total number of searches that returned + your site's listing in the unpaid results. See + the help page at + https://support.google.com/google-ads/answer/3097241 + for details. + + This field is a member of `oneof`_ ``_organic_queries``. + percent_new_visitors (float): + Percentage of first-time sessions (from + people who had never visited your site before). + Imported from Google Analytics. + + This field is a member of `oneof`_ ``_percent_new_visitors``. + phone_calls (int): + Number of offline phone calls. + + This field is a member of `oneof`_ ``_phone_calls``. + phone_impressions (int): + Number of offline phone impressions. + + This field is a member of `oneof`_ ``_phone_impressions``. + phone_through_rate (float): + Number of phone calls received (phone_calls) divided by the + number of times your phone number is shown + (phone_impressions). + + This field is a member of `oneof`_ ``_phone_through_rate``. + relative_ctr (float): + Your clickthrough rate (Ctr) divided by the + average clickthrough rate of all advertisers on + the websites that show your ads. Measures how + your ads perform on Display Network sites + compared to other ads on the same sites. + + This field is a member of `oneof`_ ``_relative_ctr``. + search_absolute_top_impression_share (float): + The percentage of the customer's Shopping or + Search ad impressions that are shown in the most + prominent Shopping position. See + https://support.google.com/google-ads/answer/7501826 + for details. Any value below 0.1 is reported as + 0.0999. + + This field is a member of `oneof`_ ``_search_absolute_top_impression_share``. + search_budget_lost_absolute_top_impression_share (float): + The number estimating how often your ad + wasn't the very first ad above the organic + search results due to a low budget. Note: Search + budget lost absolute top impression share is + reported in the range of 0 to 0.9. Any value + above 0.9 is reported as 0.9001. + + This field is a member of `oneof`_ ``_search_budget_lost_absolute_top_impression_share``. + search_budget_lost_impression_share (float): + The estimated percent of times that your ad + was eligible to show on the Search Network but + didn't because your budget was too low. Note: + Search budget lost impression share is reported + in the range of 0 to 0.9. Any value above 0.9 is + reported as 0.9001. + + This field is a member of `oneof`_ ``_search_budget_lost_impression_share``. + search_budget_lost_top_impression_share (float): + The number estimating how often your ad + didn't show anywhere above the organic search + results due to a low budget. Note: Search budget + lost top impression share is reported in the + range of 0 to 0.9. Any value above 0.9 is + reported as 0.9001. + + This field is a member of `oneof`_ ``_search_budget_lost_top_impression_share``. + search_click_share (float): + The number of clicks you've received on the + Search Network divided by the estimated number + of clicks you were eligible to receive. Note: + Search click share is reported in the range of + 0.1 to 1. Any value below 0.1 is reported as + 0.0999. + + This field is a member of `oneof`_ ``_search_click_share``. + search_exact_match_impression_share (float): + The impressions you've received divided by + the estimated number of impressions you were + eligible to receive on the Search Network for + search terms that matched your keywords exactly + (or were close variants of your keyword), + regardless of your keyword match types. Note: + Search exact match impression share is reported + in the range of 0.1 to 1. Any value below 0.1 is + reported as 0.0999. + + This field is a member of `oneof`_ ``_search_exact_match_impression_share``. + search_impression_share (float): + The impressions you've received on the Search + Network divided by the estimated number of + impressions you were eligible to receive. Note: + Search impression share is reported in the range + of 0.1 to 1. Any value below 0.1 is reported as + 0.0999. + + This field is a member of `oneof`_ ``_search_impression_share``. + search_rank_lost_absolute_top_impression_share (float): + The number estimating how often your ad + wasn't the very first ad above the organic + search results due to poor Ad Rank. Note: Search + rank lost absolute top impression share is + reported in the range of 0 to 0.9. Any value + above 0.9 is reported as 0.9001. + + This field is a member of `oneof`_ ``_search_rank_lost_absolute_top_impression_share``. + search_rank_lost_impression_share (float): + The estimated percentage of impressions on + the Search Network that your ads didn't receive + due to poor Ad Rank. Note: Search rank lost + impression share is reported in the range of 0 + to 0.9. Any value above 0.9 is reported as + 0.9001. + + This field is a member of `oneof`_ ``_search_rank_lost_impression_share``. + search_rank_lost_top_impression_share (float): + The number estimating how often your ad + didn't show anywhere above the organic search + results due to poor Ad Rank. Note: Search rank + lost top impression share is reported in the + range of 0 to 0.9. Any value above 0.9 is + reported as 0.9001. + + This field is a member of `oneof`_ ``_search_rank_lost_top_impression_share``. + search_top_impression_share (float): + The impressions you've received in the top + location (anywhere above the organic search + results) compared to the estimated number of + impressions you were eligible to receive in the + top location. Note: Search top impression share + is reported in the range of 0.1 to 1. Any value + below 0.1 is reported as 0.0999. + + This field is a member of `oneof`_ ``_search_top_impression_share``. + speed_score (int): + A measure of how quickly your page loads + after clicks on your mobile ads. The score is a + range from 1 to 10, 10 being the fastest. + + This field is a member of `oneof`_ ``_speed_score``. + top_impression_percentage (float): + The percent of your ad impressions that are + shown anywhere above the organic search results. + + This field is a member of `oneof`_ ``_top_impression_percentage``. + valid_accelerated_mobile_pages_clicks_percentage (float): + The percentage of ad clicks to Accelerated + Mobile Pages (AMP) landing pages that reach a + valid AMP page. + + This field is a member of `oneof`_ ``_valid_accelerated_mobile_pages_clicks_percentage``. + value_per_all_conversions (float): + The value of all conversions divided by the + number of all conversions. + + This field is a member of `oneof`_ ``_value_per_all_conversions``. + value_per_all_conversions_by_conversion_date (float): + The value of all conversions divided by the number of all + conversions. When this column is selected with date, the + values in date column means the conversion date. Details for + the by_conversion_date columns are available at + https://support.google.com/google-ads/answer/9549009. + + This field is a member of `oneof`_ ``_value_per_all_conversions_by_conversion_date``. + value_per_conversion (float): + The value of conversions divided by the number of + conversions. This only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_value_per_conversion``. + value_per_conversions_by_conversion_date (float): + The value of conversions divided by the number of + conversions. This only includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. When this column is selected + with date, the values in date column means the conversion + date. Details for the by_conversion_date columns are + available at + https://support.google.com/google-ads/answer/9549009. + + This field is a member of `oneof`_ ``_value_per_conversions_by_conversion_date``. + value_per_current_model_attributed_conversion (float): + The value of current model attributed conversions divided by + the number of the conversions. This only includes conversion + actions which include_in_conversions_metric attribute is set + to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_value_per_current_model_attributed_conversion``. + video_quartile_p100_rate (float): + Percentage of impressions where the viewer + watched all of your video. + + This field is a member of `oneof`_ ``_video_quartile_p100_rate``. + video_quartile_p25_rate (float): + Percentage of impressions where the viewer + watched 25% of your video. + + This field is a member of `oneof`_ ``_video_quartile_p25_rate``. + video_quartile_p50_rate (float): + Percentage of impressions where the viewer + watched 50% of your video. + + This field is a member of `oneof`_ ``_video_quartile_p50_rate``. + video_quartile_p75_rate (float): + Percentage of impressions where the viewer + watched 75% of your video. + + This field is a member of `oneof`_ ``_video_quartile_p75_rate``. + video_view_rate (float): + The number of views your TrueView video ad + receives divided by its number of impressions, + including thumbnail impressions for TrueView + in-display ads. + + This field is a member of `oneof`_ ``_video_view_rate``. + video_views (int): + The number of times your video ads were + viewed. + + This field is a member of `oneof`_ ``_video_views``. + view_through_conversions (int): + The total number of view-through conversions. + These happen when a customer sees an image or + rich media ad, then later completes a conversion + on your site without interacting with (for + example, clicking on) another ad. + + This field is a member of `oneof`_ ``_view_through_conversions``. + sk_ad_network_conversions (int): + The number of iOS Store Kit Ad Network + conversions. + publisher_purchased_clicks (int): + Clicks from properties not owned by the + publisher for which the traffic the publisher + has paid for or acquired through incentivized + activity + publisher_organic_clicks (int): + Clicks from properties for which the traffic + the publisher has not paid for or acquired + through incentivized activity + publisher_unknown_clicks (int): + Clicks from traffic which is not identified + as "Publisher Purchased" or "Publisher Organic". + all_conversions_from_location_asset_click_to_call (float): + Number of call button clicks on any location + surface after a chargeable ad event (click or + impression). This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_click_to_call``. + all_conversions_from_location_asset_directions (float): + Number of driving directions clicks on any + location surface after a chargeable ad event + (click or impression). This measure is coming + from Asset based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_directions``. + all_conversions_from_location_asset_menu (float): + Number of menu link clicks on any location + surface after a chargeable ad event (click or + impression). This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_menu``. + all_conversions_from_location_asset_order (float): + Number of order clicks on any location + surface after a chargeable ad event (click or + impression). This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_order``. + all_conversions_from_location_asset_other_engagement (float): + Number of other types of local action clicks + on any location surface after a chargeable ad + event (click or impression). This measure is + coming from Asset based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_other_engagement``. + all_conversions_from_location_asset_store_visits (float): + Estimated number of visits to the store after + a chargeable ad event (click or impression). + This measure is coming from Asset based + location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_store_visits``. + all_conversions_from_location_asset_website (float): + Number of website URL clicks on any location + surface after a chargeable ad event (click or + impression). This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_all_conversions_from_location_asset_website``. + eligible_impressions_from_location_asset_store_reach (int): + Number of impressions in which the store + location was shown or the location was used for + targeting. This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_eligible_impressions_from_location_asset_store_reach``. + view_through_conversions_from_location_asset_click_to_call (float): + Number of call button clicks on any location + surface after an impression. This measure is + coming from Asset based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_click_to_call``. + view_through_conversions_from_location_asset_directions (float): + Number of driving directions clicks on any + location surface after an impression. This + measure is coming from Asset based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_directions``. + view_through_conversions_from_location_asset_menu (float): + Number of menu link clicks on any location + surface after an impression. This measure is + coming from Asset based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_menu``. + view_through_conversions_from_location_asset_order (float): + Number of order clicks on any location + surface after an impression. This measure is + coming from Asset based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_order``. + view_through_conversions_from_location_asset_other_engagement (float): + Number of other types of local action clicks + on any location surface after an impression. + This measure is coming from Asset based + location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_other_engagement``. + view_through_conversions_from_location_asset_store_visits (float): + Estimated number of visits to the store after + an impression. This measure is coming from Asset + based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_store_visits``. + view_through_conversions_from_location_asset_website (float): + Number of website URL clicks on any location + surface after an impression. This measure is + coming from Asset based location. + + This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_website``. + """ + + absolute_top_impression_percentage = proto.Field( + proto.DOUBLE, number=183, optional=True, + ) + active_view_cpm = proto.Field(proto.DOUBLE, number=184, optional=True,) + active_view_ctr = proto.Field(proto.DOUBLE, number=185, optional=True,) + active_view_impressions = proto.Field( + proto.INT64, number=186, optional=True, + ) + active_view_measurability = proto.Field( + proto.DOUBLE, number=187, optional=True, + ) + active_view_measurable_cost_micros = proto.Field( + proto.INT64, number=188, optional=True, + ) + active_view_measurable_impressions = proto.Field( + proto.INT64, number=189, optional=True, + ) + active_view_viewability = proto.Field( + proto.DOUBLE, number=190, optional=True, + ) + all_conversions_from_interactions_rate = proto.Field( + proto.DOUBLE, number=191, optional=True, + ) + all_conversions_value = proto.Field( + proto.DOUBLE, number=192, optional=True, + ) + all_conversions_value_by_conversion_date = proto.Field( + proto.DOUBLE, number=240, + ) + all_conversions = proto.Field(proto.DOUBLE, number=193, optional=True,) + all_conversions_by_conversion_date = proto.Field(proto.DOUBLE, number=241,) + all_conversions_value_per_cost = proto.Field( + proto.DOUBLE, number=194, optional=True, + ) + all_conversions_from_click_to_call = proto.Field( + proto.DOUBLE, number=195, optional=True, + ) + all_conversions_from_directions = proto.Field( + proto.DOUBLE, number=196, optional=True, + ) + all_conversions_from_interactions_value_per_interaction = proto.Field( + proto.DOUBLE, number=197, optional=True, + ) + all_conversions_from_menu = proto.Field( + proto.DOUBLE, number=198, optional=True, + ) + all_conversions_from_order = proto.Field( + proto.DOUBLE, number=199, optional=True, + ) + all_conversions_from_other_engagement = proto.Field( + proto.DOUBLE, number=200, optional=True, + ) + all_conversions_from_store_visit = proto.Field( + proto.DOUBLE, number=201, optional=True, + ) + all_conversions_from_store_website = proto.Field( + proto.DOUBLE, number=202, optional=True, + ) + auction_insight_search_absolute_top_impression_percentage = proto.Field( + proto.DOUBLE, number=258, optional=True, + ) + auction_insight_search_impression_share = proto.Field( + proto.DOUBLE, number=259, optional=True, + ) + auction_insight_search_outranking_share = proto.Field( + proto.DOUBLE, number=260, optional=True, + ) + auction_insight_search_overlap_rate = proto.Field( + proto.DOUBLE, number=261, optional=True, + ) + auction_insight_search_position_above_rate = proto.Field( + proto.DOUBLE, number=262, optional=True, + ) + auction_insight_search_top_impression_percentage = proto.Field( + proto.DOUBLE, number=263, optional=True, + ) + average_cost = proto.Field(proto.DOUBLE, number=203, optional=True,) + average_cpc = proto.Field(proto.DOUBLE, number=204, optional=True,) + average_cpe = proto.Field(proto.DOUBLE, number=205, optional=True,) + average_cpm = proto.Field(proto.DOUBLE, number=206, optional=True,) + average_cpv = proto.Field(proto.DOUBLE, number=207, optional=True,) + average_page_views = proto.Field(proto.DOUBLE, number=208, optional=True,) + average_time_on_site = proto.Field(proto.DOUBLE, number=209, optional=True,) + benchmark_average_max_cpc = proto.Field( + proto.DOUBLE, number=210, optional=True, + ) + biddable_app_install_conversions = proto.Field( + proto.DOUBLE, number=254, optional=True, + ) + biddable_app_post_install_conversions = proto.Field( + proto.DOUBLE, number=255, optional=True, + ) + benchmark_ctr = proto.Field(proto.DOUBLE, number=211, optional=True,) + bounce_rate = proto.Field(proto.DOUBLE, number=212, optional=True,) + clicks = proto.Field(proto.INT64, number=131, optional=True,) + combined_clicks = proto.Field(proto.INT64, number=156, optional=True,) + combined_clicks_per_query = proto.Field( + proto.DOUBLE, number=157, optional=True, + ) + combined_queries = proto.Field(proto.INT64, number=158, optional=True,) + content_budget_lost_impression_share = proto.Field( + proto.DOUBLE, number=159, optional=True, + ) + content_impression_share = proto.Field( + proto.DOUBLE, number=160, optional=True, + ) + conversion_last_received_request_date_time = proto.Field( + proto.STRING, number=161, optional=True, + ) + conversion_last_conversion_date = proto.Field( + proto.STRING, number=162, optional=True, + ) + content_rank_lost_impression_share = proto.Field( + proto.DOUBLE, number=163, optional=True, + ) + conversions_from_interactions_rate = proto.Field( + proto.DOUBLE, number=164, optional=True, + ) + conversions_value = proto.Field(proto.DOUBLE, number=165, optional=True,) + conversions_value_by_conversion_date = proto.Field( + proto.DOUBLE, number=242, + ) + conversions_value_per_cost = proto.Field( + proto.DOUBLE, number=166, optional=True, + ) + conversions_from_interactions_value_per_interaction = proto.Field( + proto.DOUBLE, number=167, optional=True, + ) + conversions = proto.Field(proto.DOUBLE, number=168, optional=True,) + conversions_by_conversion_date = proto.Field(proto.DOUBLE, number=243,) + cost_micros = proto.Field(proto.INT64, number=169, optional=True,) + cost_per_all_conversions = proto.Field( + proto.DOUBLE, number=170, optional=True, + ) + cost_per_conversion = proto.Field(proto.DOUBLE, number=171, optional=True,) + cost_per_current_model_attributed_conversion = proto.Field( + proto.DOUBLE, number=172, optional=True, + ) + cross_device_conversions = proto.Field( + proto.DOUBLE, number=173, optional=True, + ) + ctr = proto.Field(proto.DOUBLE, number=174, optional=True,) + current_model_attributed_conversions = proto.Field( + proto.DOUBLE, number=175, optional=True, + ) + current_model_attributed_conversions_from_interactions_rate = proto.Field( + proto.DOUBLE, number=176, optional=True, + ) + current_model_attributed_conversions_from_interactions_value_per_interaction = proto.Field( + proto.DOUBLE, number=177, optional=True, + ) + current_model_attributed_conversions_value = proto.Field( + proto.DOUBLE, number=178, optional=True, + ) + current_model_attributed_conversions_value_per_cost = proto.Field( + proto.DOUBLE, number=179, optional=True, + ) + engagement_rate = proto.Field(proto.DOUBLE, number=180, optional=True,) + engagements = proto.Field(proto.INT64, number=181, optional=True,) + hotel_average_lead_value_micros = proto.Field( + proto.DOUBLE, number=213, optional=True, + ) + hotel_commission_rate_micros = proto.Field( + proto.INT64, number=256, optional=True, + ) + hotel_expected_commission_cost = proto.Field( + proto.DOUBLE, number=257, optional=True, + ) + hotel_price_difference_percentage = proto.Field( + proto.DOUBLE, number=214, optional=True, + ) + hotel_eligible_impressions = proto.Field( + proto.INT64, number=215, optional=True, + ) + historical_creative_quality_score = proto.Field( + proto.ENUM, + number=80, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + historical_landing_page_quality_score = proto.Field( + proto.ENUM, + number=81, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + historical_quality_score = proto.Field( + proto.INT64, number=216, optional=True, + ) + historical_search_predicted_ctr = proto.Field( + proto.ENUM, + number=83, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + gmail_forwards = proto.Field(proto.INT64, number=217, optional=True,) + gmail_saves = proto.Field(proto.INT64, number=218, optional=True,) + gmail_secondary_clicks = proto.Field( + proto.INT64, number=219, optional=True, + ) + impressions_from_store_reach = proto.Field( + proto.INT64, number=220, optional=True, + ) + impressions = proto.Field(proto.INT64, number=221, optional=True,) + interaction_rate = proto.Field(proto.DOUBLE, number=222, optional=True,) + interactions = proto.Field(proto.INT64, number=223, optional=True,) + interaction_event_types = proto.RepeatedField( + proto.ENUM, + number=100, + enum=interaction_event_type.InteractionEventTypeEnum.InteractionEventType, + ) + invalid_click_rate = proto.Field(proto.DOUBLE, number=224, optional=True,) + invalid_clicks = proto.Field(proto.INT64, number=225, optional=True,) + message_chats = proto.Field(proto.INT64, number=226, optional=True,) + message_impressions = proto.Field(proto.INT64, number=227, optional=True,) + message_chat_rate = proto.Field(proto.DOUBLE, number=228, optional=True,) + mobile_friendly_clicks_percentage = proto.Field( + proto.DOUBLE, number=229, optional=True, + ) + optimization_score_uplift = proto.Field( + proto.DOUBLE, number=247, optional=True, + ) + optimization_score_url = proto.Field( + proto.STRING, number=248, optional=True, + ) + organic_clicks = proto.Field(proto.INT64, number=230, optional=True,) + organic_clicks_per_query = proto.Field( + proto.DOUBLE, number=231, optional=True, + ) + organic_impressions = proto.Field(proto.INT64, number=232, optional=True,) + organic_impressions_per_query = proto.Field( + proto.DOUBLE, number=233, optional=True, + ) + organic_queries = proto.Field(proto.INT64, number=234, optional=True,) + percent_new_visitors = proto.Field(proto.DOUBLE, number=235, optional=True,) + phone_calls = proto.Field(proto.INT64, number=236, optional=True,) + phone_impressions = proto.Field(proto.INT64, number=237, optional=True,) + phone_through_rate = proto.Field(proto.DOUBLE, number=238, optional=True,) + relative_ctr = proto.Field(proto.DOUBLE, number=239, optional=True,) + search_absolute_top_impression_share = proto.Field( + proto.DOUBLE, number=136, optional=True, + ) + search_budget_lost_absolute_top_impression_share = proto.Field( + proto.DOUBLE, number=137, optional=True, + ) + search_budget_lost_impression_share = proto.Field( + proto.DOUBLE, number=138, optional=True, + ) + search_budget_lost_top_impression_share = proto.Field( + proto.DOUBLE, number=139, optional=True, + ) + search_click_share = proto.Field(proto.DOUBLE, number=140, optional=True,) + search_exact_match_impression_share = proto.Field( + proto.DOUBLE, number=141, optional=True, + ) + search_impression_share = proto.Field( + proto.DOUBLE, number=142, optional=True, + ) + search_rank_lost_absolute_top_impression_share = proto.Field( + proto.DOUBLE, number=143, optional=True, + ) + search_rank_lost_impression_share = proto.Field( + proto.DOUBLE, number=144, optional=True, + ) + search_rank_lost_top_impression_share = proto.Field( + proto.DOUBLE, number=145, optional=True, + ) + search_top_impression_share = proto.Field( + proto.DOUBLE, number=146, optional=True, + ) + speed_score = proto.Field(proto.INT64, number=147, optional=True,) + top_impression_percentage = proto.Field( + proto.DOUBLE, number=148, optional=True, + ) + valid_accelerated_mobile_pages_clicks_percentage = proto.Field( + proto.DOUBLE, number=149, optional=True, + ) + value_per_all_conversions = proto.Field( + proto.DOUBLE, number=150, optional=True, + ) + value_per_all_conversions_by_conversion_date = proto.Field( + proto.DOUBLE, number=244, optional=True, + ) + value_per_conversion = proto.Field(proto.DOUBLE, number=151, optional=True,) + value_per_conversions_by_conversion_date = proto.Field( + proto.DOUBLE, number=245, optional=True, + ) + value_per_current_model_attributed_conversion = proto.Field( + proto.DOUBLE, number=152, optional=True, + ) + video_quartile_p100_rate = proto.Field( + proto.DOUBLE, number=132, optional=True, + ) + video_quartile_p25_rate = proto.Field( + proto.DOUBLE, number=133, optional=True, + ) + video_quartile_p50_rate = proto.Field( + proto.DOUBLE, number=134, optional=True, + ) + video_quartile_p75_rate = proto.Field( + proto.DOUBLE, number=135, optional=True, + ) + video_view_rate = proto.Field(proto.DOUBLE, number=153, optional=True,) + video_views = proto.Field(proto.INT64, number=154, optional=True,) + view_through_conversions = proto.Field( + proto.INT64, number=155, optional=True, + ) + sk_ad_network_conversions = proto.Field(proto.INT64, number=246,) + publisher_purchased_clicks = proto.Field(proto.INT64, number=264,) + publisher_organic_clicks = proto.Field(proto.INT64, number=265,) + publisher_unknown_clicks = proto.Field(proto.INT64, number=266,) + all_conversions_from_location_asset_click_to_call = proto.Field( + proto.DOUBLE, number=267, optional=True, + ) + all_conversions_from_location_asset_directions = proto.Field( + proto.DOUBLE, number=268, optional=True, + ) + all_conversions_from_location_asset_menu = proto.Field( + proto.DOUBLE, number=269, optional=True, + ) + all_conversions_from_location_asset_order = proto.Field( + proto.DOUBLE, number=270, optional=True, + ) + all_conversions_from_location_asset_other_engagement = proto.Field( + proto.DOUBLE, number=271, optional=True, + ) + all_conversions_from_location_asset_store_visits = proto.Field( + proto.DOUBLE, number=272, optional=True, + ) + all_conversions_from_location_asset_website = proto.Field( + proto.DOUBLE, number=273, optional=True, + ) + eligible_impressions_from_location_asset_store_reach = proto.Field( + proto.INT64, number=274, optional=True, + ) + view_through_conversions_from_location_asset_click_to_call = proto.Field( + proto.DOUBLE, number=275, optional=True, + ) + view_through_conversions_from_location_asset_directions = proto.Field( + proto.DOUBLE, number=276, optional=True, + ) + view_through_conversions_from_location_asset_menu = proto.Field( + proto.DOUBLE, number=277, optional=True, + ) + view_through_conversions_from_location_asset_order = proto.Field( + proto.DOUBLE, number=278, optional=True, + ) + view_through_conversions_from_location_asset_other_engagement = proto.Field( + proto.DOUBLE, number=279, optional=True, + ) + view_through_conversions_from_location_asset_store_visits = proto.Field( + proto.DOUBLE, number=280, optional=True, + ) + view_through_conversions_from_location_asset_website = proto.Field( + proto.DOUBLE, number=281, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/offline_user_data.py b/google/ads/googleads/v12/common/types/offline_user_data.py new file mode 100644 index 000000000..0cbe7d990 --- /dev/null +++ b/google/ads/googleads/v12/common/types/offline_user_data.py @@ -0,0 +1,565 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + user_identifier_source as gage_user_identifier_source, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "OfflineUserAddressInfo", + "UserIdentifier", + "TransactionAttribute", + "StoreAttribute", + "ItemAttribute", + "UserData", + "UserAttribute", + "EventAttribute", + "EventItemAttribute", + "ShoppingLoyalty", + "CustomerMatchUserListMetadata", + "StoreSalesMetadata", + "StoreSalesThirdPartyMetadata", + }, +) + + +class OfflineUserAddressInfo(proto.Message): + r"""Address identifier of offline data. + + Attributes: + hashed_first_name (str): + First name of the user, which is hashed as + SHA-256 after normalized (Lowercase all + characters; Remove any extra spaces before, + after, and in between). + + This field is a member of `oneof`_ ``_hashed_first_name``. + hashed_last_name (str): + Last name of the user, which is hashed as + SHA-256 after normalized (lower case only and no + punctuation). + + This field is a member of `oneof`_ ``_hashed_last_name``. + city (str): + City of the address. Only accepted for Store + Sales and ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``_city``. + state (str): + State code of the address. Only accepted for + Store Sales and + ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``_state``. + country_code (str): + 2-letter country code in ISO-3166-1 alpha-2 + of the user's address. + + This field is a member of `oneof`_ ``_country_code``. + postal_code (str): + Postal code of the user's address. + + This field is a member of `oneof`_ ``_postal_code``. + hashed_street_address (str): + The street address of the user hashed using + SHA-256 hash function after normalization (lower + case only). Only accepted for + ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``_hashed_street_address``. + """ + + hashed_first_name = proto.Field(proto.STRING, number=7, optional=True,) + hashed_last_name = proto.Field(proto.STRING, number=8, optional=True,) + city = proto.Field(proto.STRING, number=9, optional=True,) + state = proto.Field(proto.STRING, number=10, optional=True,) + country_code = proto.Field(proto.STRING, number=11, optional=True,) + postal_code = proto.Field(proto.STRING, number=12, optional=True,) + hashed_street_address = proto.Field(proto.STRING, number=13, optional=True,) + + +class UserIdentifier(proto.Message): + r"""User identifying information. + + 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: + user_identifier_source (google.ads.googleads.v12.enums.types.UserIdentifierSourceEnum.UserIdentifierSource): + Source of the user identifier when the upload + is from Store Sales, ConversionUploadService, or + ConversionAdjustmentUploadService. + hashed_email (str): + Hashed email address using SHA-256 hash + function after normalization. Accepted for + Customer Match, Store Sales, + ConversionUploadService, and + ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``identifier``. + hashed_phone_number (str): + Hashed phone number using SHA-256 hash + function after normalization (E164 standard). + Accepted for Customer Match, Store Sales, + ConversionUploadService, and + ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``identifier``. + mobile_id (str): + Mobile device ID (advertising ID/IDFA). + Accepted only for Customer Match. + + This field is a member of `oneof`_ ``identifier``. + third_party_user_id (str): + Advertiser-assigned user ID for Customer + Match upload, or third-party-assigned user ID + for Store Sales. Accepted only for Customer + Match and Store Sales. + + This field is a member of `oneof`_ ``identifier``. + address_info (google.ads.googleads.v12.common.types.OfflineUserAddressInfo): + Address information. Accepted only for + Customer Match, Store Sales, and + ConversionAdjustmentUploadService. + + This field is a member of `oneof`_ ``identifier``. + """ + + user_identifier_source = proto.Field( + proto.ENUM, + number=6, + enum=gage_user_identifier_source.UserIdentifierSourceEnum.UserIdentifierSource, + ) + hashed_email = proto.Field(proto.STRING, number=7, oneof="identifier",) + hashed_phone_number = proto.Field( + proto.STRING, number=8, oneof="identifier", + ) + mobile_id = proto.Field(proto.STRING, number=9, oneof="identifier",) + third_party_user_id = proto.Field( + proto.STRING, number=10, oneof="identifier", + ) + address_info = proto.Field( + proto.MESSAGE, + number=5, + oneof="identifier", + message="OfflineUserAddressInfo", + ) + + +class TransactionAttribute(proto.Message): + r"""Attribute of the store sales transaction. + + Attributes: + transaction_date_time (str): + Timestamp when transaction occurred. Required. The format is + "YYYY-MM-DD HH:MM:SS[+/-HH:MM]", where [+/-HH:MM] is an + optional timezone offset from UTC. If the offset is absent, + the API will use the account's timezone as default. + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30+03:00". + + This field is a member of `oneof`_ ``_transaction_date_time``. + transaction_amount_micros (float): + Transaction amount in micros. Required. + Transaction amount in micros needs to be greater + than 1000. If item Attributes are provided, it + represents the total value of the items, after + multiplying the unit price per item by the + quantity provided in the ItemAttributes. + + This field is a member of `oneof`_ ``_transaction_amount_micros``. + currency_code (str): + Transaction currency code. ISO 4217 + three-letter code is used. Required. + + This field is a member of `oneof`_ ``_currency_code``. + conversion_action (str): + The resource name of conversion action to + report conversions to. Required. + + This field is a member of `oneof`_ ``_conversion_action``. + order_id (str): + Transaction order id. + Accessible only to customers on the allow-list. + + This field is a member of `oneof`_ ``_order_id``. + store_attribute (google.ads.googleads.v12.common.types.StoreAttribute): + Store attributes of the transaction. + Accessible only to customers on the allow-list. + custom_value (str): + Value of the custom variable for each + transaction. Accessible only to customers on the + allow-list. + + This field is a member of `oneof`_ ``_custom_value``. + item_attribute (google.ads.googleads.v12.common.types.ItemAttribute): + Item attributes of the transaction. + """ + + transaction_date_time = proto.Field(proto.STRING, number=8, optional=True,) + transaction_amount_micros = proto.Field( + proto.DOUBLE, number=9, optional=True, + ) + currency_code = proto.Field(proto.STRING, number=10, optional=True,) + conversion_action = proto.Field(proto.STRING, number=11, optional=True,) + order_id = proto.Field(proto.STRING, number=12, optional=True,) + store_attribute = proto.Field( + proto.MESSAGE, number=6, message="StoreAttribute", + ) + custom_value = proto.Field(proto.STRING, number=13, optional=True,) + item_attribute = proto.Field( + proto.MESSAGE, number=14, message="ItemAttribute", + ) + + +class StoreAttribute(proto.Message): + r"""Store attributes of the transaction. + + Attributes: + store_code (str): + Store code from + https://support.google.com/business/answer/3370250#storecode + + This field is a member of `oneof`_ ``_store_code``. + """ + + store_code = proto.Field(proto.STRING, number=2, optional=True,) + + +class ItemAttribute(proto.Message): + r"""Item attributes of the transaction. + + Attributes: + item_id (str): + A unique identifier of a product. It can be + either the Merchant Center Item ID or GTIN + (Global Trade Item Number). + merchant_id (int): + ID of the Merchant Center Account. + + This field is a member of `oneof`_ ``_merchant_id``. + country_code (str): + Common Locale Data Repository (CLDR) + territory code of the country associated with + the feed where your items are uploaded. See + https://developers.google.com/google-ads/api/reference/data/codes-formats#country-codes + for more information. + language_code (str): + ISO 639-1 code of the language associated + with the feed where your items are uploaded + quantity (int): + The number of items sold. Defaults to 1 if + not set. + """ + + item_id = proto.Field(proto.STRING, number=1,) + merchant_id = proto.Field(proto.INT64, number=2, optional=True,) + country_code = proto.Field(proto.STRING, number=3,) + language_code = proto.Field(proto.STRING, number=4,) + quantity = proto.Field(proto.INT64, number=5,) + + +class UserData(proto.Message): + r"""User data holding user identifiers and attributes. + + Attributes: + user_identifiers (Sequence[google.ads.googleads.v12.common.types.UserIdentifier]): + User identification info. Required. + transaction_attribute (google.ads.googleads.v12.common.types.TransactionAttribute): + Additional transactions/attributes associated + with the user. Required when updating store + sales data. + user_attribute (google.ads.googleads.v12.common.types.UserAttribute): + Additional attributes associated with the + user. Required when updating customer match + attributes. These have an expiration of 540 + days. + """ + + user_identifiers = proto.RepeatedField( + proto.MESSAGE, number=1, message="UserIdentifier", + ) + transaction_attribute = proto.Field( + proto.MESSAGE, number=2, message="TransactionAttribute", + ) + user_attribute = proto.Field( + proto.MESSAGE, number=3, message="UserAttribute", + ) + + +class UserAttribute(proto.Message): + r"""User attribute, can only be used with CUSTOMER_MATCH_WITH_ATTRIBUTES + job type. + + Attributes: + lifetime_value_micros (int): + Advertiser defined lifetime value for the + user. + + This field is a member of `oneof`_ ``_lifetime_value_micros``. + lifetime_value_bucket (int): + Advertiser defined lifetime value bucket for + the user. The valid range for a lifetime value + bucket is from 1 (low) to 10 (high), except for + remove operation where 0 will also be accepted. + + This field is a member of `oneof`_ ``_lifetime_value_bucket``. + last_purchase_date_time (str): + Timestamp of the last purchase made by the user. The format + is YYYY-MM-DD HH:MM:SS[+/-HH:MM], where [+/-HH:MM] is an + optional timezone offset from UTC. If the offset is absent, + the API will use the account's timezone as default. + average_purchase_count (int): + Advertiser defined average number of + purchases that are made by the user in a 30 day + period. + average_purchase_value_micros (int): + Advertiser defined average purchase value in + micros for the user. + acquisition_date_time (str): + Timestamp when the user was acquired. The format is + YYYY-MM-DD HH:MM:SS[+/-HH:MM], where [+/-HH:MM] is an + optional timezone offset from UTC. If the offset is absent, + the API will use the account's timezone as default. + shopping_loyalty (google.ads.googleads.v12.common.types.ShoppingLoyalty): + The shopping loyalty related data. Shopping + utilizes this data to provide users with a + better experience. Accessible only to merchants + on the allow-list with the user's consent. + + This field is a member of `oneof`_ ``_shopping_loyalty``. + lifecycle_stage (str): + Optional. Advertiser defined lifecycle stage + for the user. The accepted values are "Lead", + "Active" and "Churned". + first_purchase_date_time (str): + Optional. Timestamp of the first purchase made by the user. + The format is YYYY-MM-DD HH:MM:SS[+/-HH:MM], where + [+/-HH:MM] is an optional timezone offset from UTC. If the + offset is absent, the API will use the account's timezone as + default. + event_attribute (Sequence[google.ads.googleads.v12.common.types.EventAttribute]): + Optional. Advertiser defined events and their + attributes. All the values in the nested fields + are required. Currently this field is in beta. + """ + + lifetime_value_micros = proto.Field(proto.INT64, number=1, optional=True,) + lifetime_value_bucket = proto.Field(proto.INT32, number=2, optional=True,) + last_purchase_date_time = proto.Field(proto.STRING, number=3,) + average_purchase_count = proto.Field(proto.INT32, number=4,) + average_purchase_value_micros = proto.Field(proto.INT64, number=5,) + acquisition_date_time = proto.Field(proto.STRING, number=6,) + shopping_loyalty = proto.Field( + proto.MESSAGE, number=7, optional=True, message="ShoppingLoyalty", + ) + lifecycle_stage = proto.Field(proto.STRING, number=8,) + first_purchase_date_time = proto.Field(proto.STRING, number=9,) + event_attribute = proto.RepeatedField( + proto.MESSAGE, number=10, message="EventAttribute", + ) + + +class EventAttribute(proto.Message): + r"""Advertiser defined events and their attributes. All the + values in the nested fields are required. + + Attributes: + event (str): + Required. Advertiser defined event to be used + for remarketing. The accepted values are + "Viewed", "Cart", "Purchased" and "Recommended". + event_date_time (str): + Required. Timestamp at which the event happened. The format + is YYYY-MM-DD HH:MM:SS[+/-HH:MM], where [+/-HH:MM] is an + optional timezone offset from UTC. If the offset is absent, + the API will use the account's timezone as default. + item_attribute (Sequence[google.ads.googleads.v12.common.types.EventItemAttribute]): + Required. Item attributes of the event. + """ + + event = proto.Field(proto.STRING, number=1,) + event_date_time = proto.Field(proto.STRING, number=2,) + item_attribute = proto.RepeatedField( + proto.MESSAGE, number=3, message="EventItemAttribute", + ) + + +class EventItemAttribute(proto.Message): + r"""Event Item attributes of the Customer Match. + + Attributes: + item_id (str): + Optional. A unique identifier of a product. + It can be either the Merchant Center Item ID or + GTIN (Global Trade Item Number). + """ + + item_id = proto.Field(proto.STRING, number=1,) + + +class ShoppingLoyalty(proto.Message): + r"""The shopping loyalty related data. Shopping utilizes this + data to provide users with a better experience. + Accessible only to merchants on the allow-list. + + Attributes: + loyalty_tier (str): + The membership tier. It is a free-form string + as each merchant may have their own loyalty + system. For example, it could be a number from 1 + to 10, or a string such as "Golden" or "Silver", + or even empty string "". + + This field is a member of `oneof`_ ``_loyalty_tier``. + """ + + loyalty_tier = proto.Field(proto.STRING, number=1, optional=True,) + + +class CustomerMatchUserListMetadata(proto.Message): + r"""Metadata for customer match user list. + + Attributes: + user_list (str): + The resource name of remarketing list to update data. + Required for job of CUSTOMER_MATCH_USER_LIST type. + + This field is a member of `oneof`_ ``_user_list``. + """ + + user_list = proto.Field(proto.STRING, number=2, optional=True,) + + +class StoreSalesMetadata(proto.Message): + r"""Metadata for Store Sales Direct. + + Attributes: + loyalty_fraction (float): + This is the fraction of all transactions that + are identifiable (for example, associated with + any form of customer information). Required. The + fraction needs to be between 0 and 1 (excluding + 0). + + This field is a member of `oneof`_ ``_loyalty_fraction``. + transaction_upload_fraction (float): + This is the ratio of sales being uploaded + compared to the overall sales that can be + associated with a customer. Required. The + fraction needs to be between 0 and 1 (excluding + 0). For example, if you upload half the sales + that you are able to associate with a customer, + this would be 0.5. + + This field is a member of `oneof`_ ``_transaction_upload_fraction``. + custom_key (str): + Name of the store sales custom variable key. + A predefined key that can be applied to the + transaction and then later used for custom + segmentation in reporting. + Accessible only to customers on the allow-list. + + This field is a member of `oneof`_ ``_custom_key``. + third_party_metadata (google.ads.googleads.v12.common.types.StoreSalesThirdPartyMetadata): + Metadata for a third party Store Sales + upload. + """ + + loyalty_fraction = proto.Field(proto.DOUBLE, number=5, optional=True,) + transaction_upload_fraction = proto.Field( + proto.DOUBLE, number=6, optional=True, + ) + custom_key = proto.Field(proto.STRING, number=7, optional=True,) + third_party_metadata = proto.Field( + proto.MESSAGE, number=3, message="StoreSalesThirdPartyMetadata", + ) + + +class StoreSalesThirdPartyMetadata(proto.Message): + r"""Metadata for a third party Store Sales. + This product is only for customers on the allow-list. Contact + your Google business development representative for details on + the upload configuration. + + Attributes: + advertiser_upload_date_time (str): + Time the advertiser uploaded the data to the + partner. Required. The format is "YYYY-MM-DD + HH:MM:SS". Examples: "2018-03-05 09:15:00" or + "2018-02-01 14:34:30". + + This field is a member of `oneof`_ ``_advertiser_upload_date_time``. + valid_transaction_fraction (float): + The fraction of transactions that are valid. + Invalid transactions may include invalid formats + or values. Required. + The fraction needs to be between 0 and 1 + (excluding 0). + + This field is a member of `oneof`_ ``_valid_transaction_fraction``. + partner_match_fraction (float): + The fraction of valid transactions that are + matched to a third party assigned user ID on the + partner side. Required. + The fraction needs to be between 0 and 1 + (excluding 0). + + This field is a member of `oneof`_ ``_partner_match_fraction``. + partner_upload_fraction (float): + The fraction of valid transactions that are + uploaded by the partner to Google. + Required. + The fraction needs to be between 0 and 1 + (excluding 0). + + This field is a member of `oneof`_ ``_partner_upload_fraction``. + bridge_map_version_id (str): + Version of partner IDs to be used for + uploads. Required. + + This field is a member of `oneof`_ ``_bridge_map_version_id``. + partner_id (int): + ID of the third party partner updating the + transaction feed. + + This field is a member of `oneof`_ ``_partner_id``. + """ + + advertiser_upload_date_time = proto.Field( + proto.STRING, number=7, optional=True, + ) + valid_transaction_fraction = proto.Field( + proto.DOUBLE, number=8, optional=True, + ) + partner_match_fraction = proto.Field(proto.DOUBLE, number=9, optional=True,) + partner_upload_fraction = proto.Field( + proto.DOUBLE, number=10, optional=True, + ) + bridge_map_version_id = proto.Field(proto.STRING, number=11, optional=True,) + partner_id = proto.Field(proto.INT64, number=12, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/policy.py b/google/ads/googleads/v12/common/types/policy.py new file mode 100644 index 000000000..caa8dd8a8 --- /dev/null +++ b/google/ads/googleads/v12/common/types/policy.py @@ -0,0 +1,402 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import policy_topic_entry_type +from google.ads.googleads.v12.enums.types import ( + policy_topic_evidence_destination_mismatch_url_type, +) +from google.ads.googleads.v12.enums.types import ( + policy_topic_evidence_destination_not_working_device, +) +from google.ads.googleads.v12.enums.types import ( + policy_topic_evidence_destination_not_working_dns_error_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "PolicyViolationKey", + "PolicyValidationParameter", + "PolicyTopicEntry", + "PolicyTopicEvidence", + "PolicyTopicConstraint", + }, +) + + +class PolicyViolationKey(proto.Message): + r"""Key of the violation. The key is used for referring to a + violation when filing an exemption request. + + Attributes: + policy_name (str): + Unique ID of the violated policy. + + This field is a member of `oneof`_ ``_policy_name``. + violating_text (str): + The text that violates the policy if + specified. Otherwise, refers to the policy in + general (for example, when requesting to be + exempt from the whole policy). If not specified + for criterion exemptions, the whole policy is + implied. Must be specified for ad exemptions. + + This field is a member of `oneof`_ ``_violating_text``. + """ + + policy_name = proto.Field(proto.STRING, number=3, optional=True,) + violating_text = proto.Field(proto.STRING, number=4, optional=True,) + + +class PolicyValidationParameter(proto.Message): + r"""Parameter for controlling how policy exemption is done. + + Attributes: + ignorable_policy_topics (Sequence[str]): + The list of policy topics that should not + cause a PolicyFindingError to be reported. This + field is currently only compatible with Enhanced + Text Ad. It corresponds to the + PolicyTopicEntry.topic field. + Resources violating these policies will be + saved, but will not be eligible to serve. They + may begin serving at a later time due to a + change in policies, re-review of the resource, + or a change in advertiser certificates. + exempt_policy_violation_keys (Sequence[google.ads.googleads.v12.common.types.PolicyViolationKey]): + The list of policy violation keys that should not cause a + PolicyViolationError to be reported. Not all policy + violations are exemptable, refer to the is_exemptible field + in the returned PolicyViolationError. + + Resources violating these polices will be saved, but will + not be eligible to serve. They may begin serving at a later + time due to a change in policies, re-review of the resource, + or a change in advertiser certificates. + """ + + ignorable_policy_topics = proto.RepeatedField(proto.STRING, number=3,) + exempt_policy_violation_keys = proto.RepeatedField( + proto.MESSAGE, number=2, message="PolicyViolationKey", + ) + + +class PolicyTopicEntry(proto.Message): + r"""Policy finding attached to a resource (for example, alcohol + policy associated with a site that sells alcohol). + + Each PolicyTopicEntry has a topic that indicates the specific + ads policy the entry is about and a type to indicate the effect + that the entry will have on serving. It may optionally have one + or more evidences that indicate the reason for the finding. It + may also optionally have one or more constraints that provide + details about how serving may be restricted. + + Attributes: + topic (str): + Policy topic this finding refers to. For example, "ALCOHOL", + "TRADEMARKS_IN_AD_TEXT", or "DESTINATION_NOT_WORKING". The + set of possible policy topics is not fixed for a particular + API version and may change at any time. + + This field is a member of `oneof`_ ``_topic``. + type_ (google.ads.googleads.v12.enums.types.PolicyTopicEntryTypeEnum.PolicyTopicEntryType): + Describes the negative or positive effect + this policy will have on serving. + evidences (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEvidence]): + Additional information that explains policy + finding (for example, the brand name for a + trademark finding). + constraints (Sequence[google.ads.googleads.v12.common.types.PolicyTopicConstraint]): + Indicates how serving of this resource may be + affected (for example, not serving in a + country). + """ + + topic = proto.Field(proto.STRING, number=5, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=2, + enum=policy_topic_entry_type.PolicyTopicEntryTypeEnum.PolicyTopicEntryType, + ) + evidences = proto.RepeatedField( + proto.MESSAGE, number=3, message="PolicyTopicEvidence", + ) + constraints = proto.RepeatedField( + proto.MESSAGE, number=4, message="PolicyTopicConstraint", + ) + + +class PolicyTopicEvidence(proto.Message): + r"""Additional information that explains a policy finding. + + 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: + website_list (google.ads.googleads.v12.common.types.PolicyTopicEvidence.WebsiteList): + List of websites linked with this resource. + + This field is a member of `oneof`_ ``value``. + text_list (google.ads.googleads.v12.common.types.PolicyTopicEvidence.TextList): + List of evidence found in the text of a + resource. + + This field is a member of `oneof`_ ``value``. + language_code (str): + The language the resource was detected to be + written in. This is an IETF language tag such as + "en-US". + + This field is a member of `oneof`_ ``value``. + destination_text_list (google.ads.googleads.v12.common.types.PolicyTopicEvidence.DestinationTextList): + The text in the destination of the resource + that is causing a policy finding. + + This field is a member of `oneof`_ ``value``. + destination_mismatch (google.ads.googleads.v12.common.types.PolicyTopicEvidence.DestinationMismatch): + Mismatch between the destinations of a + resource's URLs. + + This field is a member of `oneof`_ ``value``. + destination_not_working (google.ads.googleads.v12.common.types.PolicyTopicEvidence.DestinationNotWorking): + Details when the destination is returning an + HTTP error code or isn't functional in all + locations for commonly used devices. + + This field is a member of `oneof`_ ``value``. + """ + + class TextList(proto.Message): + r"""A list of fragments of text that violated a policy. + + Attributes: + texts (Sequence[str]): + The fragments of text from the resource that + caused the policy finding. + """ + + texts = proto.RepeatedField(proto.STRING, number=2,) + + class WebsiteList(proto.Message): + r"""A list of websites that caused a policy finding. Used for + ONE_WEBSITE_PER_AD_GROUP policy topic, for example. In case there + are more than five websites, only the top five (those that appear in + resources the most) will be listed here. + + Attributes: + websites (Sequence[str]): + Websites that caused the policy finding. + """ + + websites = proto.RepeatedField(proto.STRING, number=2,) + + class DestinationTextList(proto.Message): + r"""A list of strings found in a destination page that caused a + policy finding. + + Attributes: + destination_texts (Sequence[str]): + List of text found in the resource's + destination page. + """ + + destination_texts = proto.RepeatedField(proto.STRING, number=2,) + + class DestinationMismatch(proto.Message): + r"""Evidence of mismatches between the URLs of a resource. + + Attributes: + url_types (Sequence[google.ads.googleads.v12.enums.types.PolicyTopicEvidenceDestinationMismatchUrlTypeEnum.PolicyTopicEvidenceDestinationMismatchUrlType]): + The set of URLs that did not match each + other. + """ + + url_types = proto.RepeatedField( + proto.ENUM, + number=1, + enum=policy_topic_evidence_destination_mismatch_url_type.PolicyTopicEvidenceDestinationMismatchUrlTypeEnum.PolicyTopicEvidenceDestinationMismatchUrlType, + ) + + class DestinationNotWorking(proto.Message): + r"""Evidence details when the destination is returning an HTTP + error code or isn't functional in all locations for commonly + used devices. + + 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: + expanded_url (str): + The full URL that didn't work. + + This field is a member of `oneof`_ ``_expanded_url``. + device (google.ads.googleads.v12.enums.types.PolicyTopicEvidenceDestinationNotWorkingDeviceEnum.PolicyTopicEvidenceDestinationNotWorkingDevice): + The type of device that failed to load the + URL. + last_checked_date_time (str): + The time the URL was last checked. + The format is "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_last_checked_date_time``. + dns_error_type (google.ads.googleads.v12.enums.types.PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum.PolicyTopicEvidenceDestinationNotWorkingDnsErrorType): + The type of DNS error. + + This field is a member of `oneof`_ ``reason``. + http_error_code (int): + The HTTP error code. + + This field is a member of `oneof`_ ``reason``. + """ + + expanded_url = proto.Field(proto.STRING, number=7, optional=True,) + device = proto.Field( + proto.ENUM, + number=4, + enum=policy_topic_evidence_destination_not_working_device.PolicyTopicEvidenceDestinationNotWorkingDeviceEnum.PolicyTopicEvidenceDestinationNotWorkingDevice, + ) + last_checked_date_time = proto.Field( + proto.STRING, number=8, optional=True, + ) + dns_error_type = proto.Field( + proto.ENUM, + number=1, + oneof="reason", + enum=policy_topic_evidence_destination_not_working_dns_error_type.PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum.PolicyTopicEvidenceDestinationNotWorkingDnsErrorType, + ) + http_error_code = proto.Field(proto.INT64, number=6, oneof="reason",) + + website_list = proto.Field( + proto.MESSAGE, number=3, oneof="value", message=WebsiteList, + ) + text_list = proto.Field( + proto.MESSAGE, number=4, oneof="value", message=TextList, + ) + language_code = proto.Field(proto.STRING, number=9, oneof="value",) + destination_text_list = proto.Field( + proto.MESSAGE, number=6, oneof="value", message=DestinationTextList, + ) + destination_mismatch = proto.Field( + proto.MESSAGE, number=7, oneof="value", message=DestinationMismatch, + ) + destination_not_working = proto.Field( + proto.MESSAGE, number=8, oneof="value", message=DestinationNotWorking, + ) + + +class PolicyTopicConstraint(proto.Message): + r"""Describes the effect on serving that a policy topic entry + will have. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + country_constraint_list (google.ads.googleads.v12.common.types.PolicyTopicConstraint.CountryConstraintList): + Countries where the resource cannot serve. + + This field is a member of `oneof`_ ``value``. + reseller_constraint (google.ads.googleads.v12.common.types.PolicyTopicConstraint.ResellerConstraint): + Reseller constraint. + + This field is a member of `oneof`_ ``value``. + certificate_missing_in_country_list (google.ads.googleads.v12.common.types.PolicyTopicConstraint.CountryConstraintList): + Countries where a certificate is required for + serving. + + This field is a member of `oneof`_ ``value``. + certificate_domain_mismatch_in_country_list (google.ads.googleads.v12.common.types.PolicyTopicConstraint.CountryConstraintList): + Countries where the resource's domain is not + covered by the certificates associated with it. + + This field is a member of `oneof`_ ``value``. + """ + + class CountryConstraintList(proto.Message): + r"""A list of countries where a resource's serving is + constrained. + + Attributes: + total_targeted_countries (int): + Total number of countries targeted by the + resource. + + This field is a member of `oneof`_ ``_total_targeted_countries``. + countries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicConstraint.CountryConstraint]): + Countries in which serving is restricted. + """ + + total_targeted_countries = proto.Field( + proto.INT32, number=3, optional=True, + ) + countries = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="PolicyTopicConstraint.CountryConstraint", + ) + + class ResellerConstraint(proto.Message): + r"""Indicates that a policy topic was constrained due to + disapproval of the website for reseller purposes. + + """ + + class CountryConstraint(proto.Message): + r"""Indicates that a resource's ability to serve in a particular + country is constrained. + + Attributes: + country_criterion (str): + Geo target constant resource name of the + country in which serving is constrained. + + This field is a member of `oneof`_ ``_country_criterion``. + """ + + country_criterion = proto.Field(proto.STRING, number=2, optional=True,) + + country_constraint_list = proto.Field( + proto.MESSAGE, number=1, oneof="value", message=CountryConstraintList, + ) + reseller_constraint = proto.Field( + proto.MESSAGE, number=2, oneof="value", message=ResellerConstraint, + ) + certificate_missing_in_country_list = proto.Field( + proto.MESSAGE, number=3, oneof="value", message=CountryConstraintList, + ) + certificate_domain_mismatch_in_country_list = proto.Field( + proto.MESSAGE, number=4, oneof="value", message=CountryConstraintList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/policy_summary.py b/google/ads/googleads/v12/common/types/policy_summary.py new file mode 100644 index 000000000..efde16b6b --- /dev/null +++ b/google/ads/googleads/v12/common/types/policy_summary.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"PolicySummary",}, +) + + +class PolicySummary(proto.Message): + r"""Contains policy summary information. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + The list of policy findings. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Where in the review process the resource is. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + The overall approval status, which is + calculated based on the status of its individual + policy topic entries. + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + review_status = proto.Field( + proto.ENUM, + number=2, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/real_time_bidding_setting.py b/google/ads/googleads/v12/common/types/real_time_bidding_setting.py new file mode 100644 index 000000000..509d583d9 --- /dev/null +++ b/google/ads/googleads/v12/common/types/real_time_bidding_setting.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"RealTimeBiddingSetting",}, +) + + +class RealTimeBiddingSetting(proto.Message): + r"""Settings for Real-Time Bidding, a feature only available for + campaigns targeting the Ad Exchange network. + + Attributes: + opt_in (bool): + Whether the campaign is opted in to real-time + bidding. + + This field is a member of `oneof`_ ``_opt_in``. + """ + + opt_in = proto.Field(proto.BOOL, number=2, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/segments.py b/google/ads/googleads/v12/common/types/segments.py new file mode 100644 index 000000000..c38ee341f --- /dev/null +++ b/google/ads/googleads/v12/common/types/segments.py @@ -0,0 +1,774 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import ( + ad_destination_type as gage_ad_destination_type, +) +from google.ads.googleads.v12.enums.types import ( + ad_network_type as gage_ad_network_type, +) +from google.ads.googleads.v12.enums.types import ( + budget_campaign_association_status as gage_budget_campaign_association_status, +) +from google.ads.googleads.v12.enums.types import click_type as gage_click_type +from google.ads.googleads.v12.enums.types import ( + conversion_action_category as gage_conversion_action_category, +) +from google.ads.googleads.v12.enums.types import ( + conversion_attribution_event_type as gage_conversion_attribution_event_type, +) +from google.ads.googleads.v12.enums.types import ( + conversion_lag_bucket as gage_conversion_lag_bucket, +) +from google.ads.googleads.v12.enums.types import ( + conversion_or_adjustment_lag_bucket as gage_conversion_or_adjustment_lag_bucket, +) +from google.ads.googleads.v12.enums.types import ( + conversion_value_rule_primary_dimension as gage_conversion_value_rule_primary_dimension, +) +from google.ads.googleads.v12.enums.types import day_of_week as gage_day_of_week +from google.ads.googleads.v12.enums.types import device as gage_device +from google.ads.googleads.v12.enums.types import ( + external_conversion_source as gage_external_conversion_source, +) +from google.ads.googleads.v12.enums.types import ( + hotel_date_selection_type as gage_hotel_date_selection_type, +) +from google.ads.googleads.v12.enums.types import ( + hotel_price_bucket as gage_hotel_price_bucket, +) +from google.ads.googleads.v12.enums.types import ( + hotel_rate_type as gage_hotel_rate_type, +) +from google.ads.googleads.v12.enums.types import ( + month_of_year as gage_month_of_year, +) +from google.ads.googleads.v12.enums.types import ( + placeholder_type as gage_placeholder_type, +) +from google.ads.googleads.v12.enums.types import ( + product_channel as gage_product_channel, +) +from google.ads.googleads.v12.enums.types import ( + product_channel_exclusivity as gage_product_channel_exclusivity, +) +from google.ads.googleads.v12.enums.types import ( + product_condition as gage_product_condition, +) +from google.ads.googleads.v12.enums.types import ( + recommendation_type as gage_recommendation_type, +) +from google.ads.googleads.v12.enums.types import ( + search_engine_results_page_type as gage_search_engine_results_page_type, +) +from google.ads.googleads.v12.enums.types import ( + search_term_match_type as gage_search_term_match_type, +) +from google.ads.googleads.v12.enums.types import ( + sk_ad_network_ad_event_type as gage_sk_ad_network_ad_event_type, +) +from google.ads.googleads.v12.enums.types import ( + sk_ad_network_attribution_credit as gage_sk_ad_network_attribution_credit, +) +from google.ads.googleads.v12.enums.types import ( + sk_ad_network_user_type as gage_sk_ad_network_user_type, +) +from google.ads.googleads.v12.enums.types import slot as gage_slot + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "Segments", + "Keyword", + "BudgetCampaignAssociationStatus", + "AssetInteractionTarget", + "SkAdNetworkSourceApp", + }, +) + + +class Segments(proto.Message): + r"""Segment only fields. + + Attributes: + ad_destination_type (google.ads.googleads.v12.enums.types.AdDestinationTypeEnum.AdDestinationType): + Ad Destination type. + ad_network_type (google.ads.googleads.v12.enums.types.AdNetworkTypeEnum.AdNetworkType): + Ad network type. + auction_insight_domain (str): + Domain (visible URL) of a participant in the + Auction Insights report. + + This field is a member of `oneof`_ ``_auction_insight_domain``. + budget_campaign_association_status (google.ads.googleads.v12.common.types.BudgetCampaignAssociationStatus): + Budget campaign association status. + click_type (google.ads.googleads.v12.enums.types.ClickTypeEnum.ClickType): + Click type. + conversion_action (str): + Resource name of the conversion action. + + This field is a member of `oneof`_ ``_conversion_action``. + conversion_action_category (google.ads.googleads.v12.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + Conversion action category. + conversion_action_name (str): + Conversion action name. + + This field is a member of `oneof`_ ``_conversion_action_name``. + conversion_adjustment (bool): + This segments your conversion columns by the + original conversion and conversion value versus + the delta if conversions were adjusted. False + row has the data as originally stated; While + true row has the delta between data now and the + data as originally stated. Summing the two + together results post-adjustment data. + + This field is a member of `oneof`_ ``_conversion_adjustment``. + conversion_attribution_event_type (google.ads.googleads.v12.enums.types.ConversionAttributionEventTypeEnum.ConversionAttributionEventType): + Conversion attribution event type. + conversion_lag_bucket (google.ads.googleads.v12.enums.types.ConversionLagBucketEnum.ConversionLagBucket): + An enum value representing the number of days + between the impression and the conversion. + conversion_or_adjustment_lag_bucket (google.ads.googleads.v12.enums.types.ConversionOrAdjustmentLagBucketEnum.ConversionOrAdjustmentLagBucket): + An enum value representing the number of days + between the impression and the conversion or + between the impression and adjustments to the + conversion. + date (str): + Date to which metrics apply. + yyyy-MM-dd format, for example, 2018-04-17. + + This field is a member of `oneof`_ ``_date``. + day_of_week (google.ads.googleads.v12.enums.types.DayOfWeekEnum.DayOfWeek): + Day of the week, for example, MONDAY. + device (google.ads.googleads.v12.enums.types.DeviceEnum.Device): + Device to which metrics apply. + external_conversion_source (google.ads.googleads.v12.enums.types.ExternalConversionSourceEnum.ExternalConversionSource): + External conversion source. + geo_target_airport (str): + Resource name of the geo target constant that + represents an airport. + + This field is a member of `oneof`_ ``_geo_target_airport``. + geo_target_canton (str): + Resource name of the geo target constant that + represents a canton. + + This field is a member of `oneof`_ ``_geo_target_canton``. + geo_target_city (str): + Resource name of the geo target constant that + represents a city. + + This field is a member of `oneof`_ ``_geo_target_city``. + geo_target_country (str): + Resource name of the geo target constant that + represents a country. + + This field is a member of `oneof`_ ``_geo_target_country``. + geo_target_county (str): + Resource name of the geo target constant that + represents a county. + + This field is a member of `oneof`_ ``_geo_target_county``. + geo_target_district (str): + Resource name of the geo target constant that + represents a district. + + This field is a member of `oneof`_ ``_geo_target_district``. + geo_target_metro (str): + Resource name of the geo target constant that + represents a metro. + + This field is a member of `oneof`_ ``_geo_target_metro``. + geo_target_most_specific_location (str): + Resource name of the geo target constant that + represents the most specific location. + + This field is a member of `oneof`_ ``_geo_target_most_specific_location``. + geo_target_postal_code (str): + Resource name of the geo target constant that + represents a postal code. + + This field is a member of `oneof`_ ``_geo_target_postal_code``. + geo_target_province (str): + Resource name of the geo target constant that + represents a province. + + This field is a member of `oneof`_ ``_geo_target_province``. + geo_target_region (str): + Resource name of the geo target constant that + represents a region. + + This field is a member of `oneof`_ ``_geo_target_region``. + geo_target_state (str): + Resource name of the geo target constant that + represents a state. + + This field is a member of `oneof`_ ``_geo_target_state``. + hotel_booking_window_days (int): + Hotel booking window in days. + + This field is a member of `oneof`_ ``_hotel_booking_window_days``. + hotel_center_id (int): + Hotel center ID. + + This field is a member of `oneof`_ ``_hotel_center_id``. + hotel_check_in_date (str): + Hotel check-in date. Formatted as yyyy-MM-dd. + + This field is a member of `oneof`_ ``_hotel_check_in_date``. + hotel_check_in_day_of_week (google.ads.googleads.v12.enums.types.DayOfWeekEnum.DayOfWeek): + Hotel check-in day of week. + hotel_city (str): + Hotel city. + + This field is a member of `oneof`_ ``_hotel_city``. + hotel_class (int): + Hotel class. + + This field is a member of `oneof`_ ``_hotel_class``. + hotel_country (str): + Hotel country. + + This field is a member of `oneof`_ ``_hotel_country``. + hotel_date_selection_type (google.ads.googleads.v12.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): + Hotel date selection type. + hotel_length_of_stay (int): + Hotel length of stay. + + This field is a member of `oneof`_ ``_hotel_length_of_stay``. + hotel_rate_rule_id (str): + Hotel rate rule ID. + + This field is a member of `oneof`_ ``_hotel_rate_rule_id``. + hotel_rate_type (google.ads.googleads.v12.enums.types.HotelRateTypeEnum.HotelRateType): + Hotel rate type. + hotel_price_bucket (google.ads.googleads.v12.enums.types.HotelPriceBucketEnum.HotelPriceBucket): + Hotel price bucket. + hotel_state (str): + Hotel state. + + This field is a member of `oneof`_ ``_hotel_state``. + hour (int): + Hour of day as a number between 0 and 23, + inclusive. + + This field is a member of `oneof`_ ``_hour``. + interaction_on_this_extension (bool): + Only used with feed item metrics. + Indicates whether the interaction metrics + occurred on the feed item itself or a different + extension or ad unit. + + This field is a member of `oneof`_ ``_interaction_on_this_extension``. + keyword (google.ads.googleads.v12.common.types.Keyword): + Keyword criterion. + month (str): + Month as represented by the date of the first + day of a month. Formatted as yyyy-MM-dd. + + This field is a member of `oneof`_ ``_month``. + month_of_year (google.ads.googleads.v12.enums.types.MonthOfYearEnum.MonthOfYear): + Month of the year, for example, January. + partner_hotel_id (str): + Partner hotel ID. + + This field is a member of `oneof`_ ``_partner_hotel_id``. + placeholder_type (google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType): + Placeholder type. This is only used with feed + item metrics. + product_aggregator_id (int): + Aggregator ID of the product. + + This field is a member of `oneof`_ ``_product_aggregator_id``. + product_bidding_category_level1 (str): + Bidding category (level 1) of the product. + + This field is a member of `oneof`_ ``_product_bidding_category_level1``. + product_bidding_category_level2 (str): + Bidding category (level 2) of the product. + + This field is a member of `oneof`_ ``_product_bidding_category_level2``. + product_bidding_category_level3 (str): + Bidding category (level 3) of the product. + + This field is a member of `oneof`_ ``_product_bidding_category_level3``. + product_bidding_category_level4 (str): + Bidding category (level 4) of the product. + + This field is a member of `oneof`_ ``_product_bidding_category_level4``. + product_bidding_category_level5 (str): + Bidding category (level 5) of the product. + + This field is a member of `oneof`_ ``_product_bidding_category_level5``. + product_brand (str): + Brand of the product. + + This field is a member of `oneof`_ ``_product_brand``. + product_channel (google.ads.googleads.v12.enums.types.ProductChannelEnum.ProductChannel): + Channel of the product. + product_channel_exclusivity (google.ads.googleads.v12.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): + Channel exclusivity of the product. + product_condition (google.ads.googleads.v12.enums.types.ProductConditionEnum.ProductCondition): + Condition of the product. + product_country (str): + Resource name of the geo target constant for + the country of sale of the product. + + This field is a member of `oneof`_ ``_product_country``. + product_custom_attribute0 (str): + Custom attribute 0 of the product. + + This field is a member of `oneof`_ ``_product_custom_attribute0``. + product_custom_attribute1 (str): + Custom attribute 1 of the product. + + This field is a member of `oneof`_ ``_product_custom_attribute1``. + product_custom_attribute2 (str): + Custom attribute 2 of the product. + + This field is a member of `oneof`_ ``_product_custom_attribute2``. + product_custom_attribute3 (str): + Custom attribute 3 of the product. + + This field is a member of `oneof`_ ``_product_custom_attribute3``. + product_custom_attribute4 (str): + Custom attribute 4 of the product. + + This field is a member of `oneof`_ ``_product_custom_attribute4``. + product_item_id (str): + Item ID of the product. + + This field is a member of `oneof`_ ``_product_item_id``. + product_language (str): + Resource name of the language constant for + the language of the product. + + This field is a member of `oneof`_ ``_product_language``. + product_merchant_id (int): + Merchant ID of the product. + + This field is a member of `oneof`_ ``_product_merchant_id``. + product_store_id (str): + Store ID of the product. + + This field is a member of `oneof`_ ``_product_store_id``. + product_title (str): + Title of the product. + + This field is a member of `oneof`_ ``_product_title``. + product_type_l1 (str): + Type (level 1) of the product. + + This field is a member of `oneof`_ ``_product_type_l1``. + product_type_l2 (str): + Type (level 2) of the product. + + This field is a member of `oneof`_ ``_product_type_l2``. + product_type_l3 (str): + Type (level 3) of the product. + + This field is a member of `oneof`_ ``_product_type_l3``. + product_type_l4 (str): + Type (level 4) of the product. + + This field is a member of `oneof`_ ``_product_type_l4``. + product_type_l5 (str): + Type (level 5) of the product. + + This field is a member of `oneof`_ ``_product_type_l5``. + quarter (str): + Quarter as represented by the date of the + first day of a quarter. Uses the calendar year + for quarters, for example, the second quarter of + 2018 starts on 2018-04-01. Formatted as + yyyy-MM-dd. + + This field is a member of `oneof`_ ``_quarter``. + recommendation_type (google.ads.googleads.v12.enums.types.RecommendationTypeEnum.RecommendationType): + Recommendation type. + search_engine_results_page_type (google.ads.googleads.v12.enums.types.SearchEngineResultsPageTypeEnum.SearchEngineResultsPageType): + Type of the search engine results page. + search_term_match_type (google.ads.googleads.v12.enums.types.SearchTermMatchTypeEnum.SearchTermMatchType): + Match type of the keyword that triggered the + ad, including variants. + slot (google.ads.googleads.v12.enums.types.SlotEnum.Slot): + Position of the ad. + conversion_value_rule_primary_dimension (google.ads.googleads.v12.enums.types.ConversionValueRulePrimaryDimensionEnum.ConversionValueRulePrimaryDimension): + Primary dimension of applied conversion value rules. + NO_RULE_APPLIED shows the total recorded value of + conversions that do not have a value rule applied. ORIGINAL + shows the original value of conversions to which a value + rule has been applied. GEO_LOCATION, DEVICE, AUDIENCE show + the net adjustment after value rules were applied. + webpage (str): + Resource name of the ad group criterion that + represents webpage criterion. + + This field is a member of `oneof`_ ``_webpage``. + week (str): + Week as defined as Monday through Sunday, and + represented by the date of Monday. Formatted as + yyyy-MM-dd. + + This field is a member of `oneof`_ ``_week``. + year (int): + Year, formatted as yyyy. + + This field is a member of `oneof`_ ``_year``. + sk_ad_network_conversion_value (int): + iOS Store Kit Ad Network conversion value. + Null value means this segment is not applicable, + for example, non-iOS campaign. + + This field is a member of `oneof`_ ``_sk_ad_network_conversion_value``. + sk_ad_network_user_type (google.ads.googleads.v12.enums.types.SkAdNetworkUserTypeEnum.SkAdNetworkUserType): + iOS Store Kit Ad Network user type. + sk_ad_network_ad_event_type (google.ads.googleads.v12.enums.types.SkAdNetworkAdEventTypeEnum.SkAdNetworkAdEventType): + iOS Store Kit Ad Network ad event type. + sk_ad_network_source_app (google.ads.googleads.v12.common.types.SkAdNetworkSourceApp): + App where the ad that drove the iOS Store Kit + Ad Network install was shown. Null value means + this segment is not applicable, for example, + non-iOS campaign, or was not present in any + postbacks sent by Apple. + + This field is a member of `oneof`_ ``_sk_ad_network_source_app``. + sk_ad_network_attribution_credit (google.ads.googleads.v12.enums.types.SkAdNetworkAttributionCreditEnum.SkAdNetworkAttributionCredit): + iOS Store Kit Ad Network attribution credit + asset_interaction_target (google.ads.googleads.v12.common.types.AssetInteractionTarget): + Only used with CustomerAsset, CampaignAsset and AdGroupAsset + metrics. Indicates whether the interaction metrics occurred + on the asset itself or a different asset or ad unit. + Interactions (for example, clicks) are counted across all + the parts of the served ad (for example, Ad itself and other + components like Sitelinks) when they are served together. + When interaction_on_this_asset is true, it means the + interactions are on this specific asset and when + interaction_on_this_asset is false, it means the + interactions is not on this specific asset but on other + parts of the served ad this asset is served with. + + This field is a member of `oneof`_ ``_asset_interaction_target``. + """ + + ad_destination_type = proto.Field( + proto.ENUM, + number=136, + enum=gage_ad_destination_type.AdDestinationTypeEnum.AdDestinationType, + ) + ad_network_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_ad_network_type.AdNetworkTypeEnum.AdNetworkType, + ) + auction_insight_domain = proto.Field( + proto.STRING, number=145, optional=True, + ) + budget_campaign_association_status = proto.Field( + proto.MESSAGE, number=134, message="BudgetCampaignAssociationStatus", + ) + click_type = proto.Field( + proto.ENUM, number=26, enum=gage_click_type.ClickTypeEnum.ClickType, + ) + conversion_action = proto.Field(proto.STRING, number=113, optional=True,) + conversion_action_category = proto.Field( + proto.ENUM, + number=53, + enum=gage_conversion_action_category.ConversionActionCategoryEnum.ConversionActionCategory, + ) + conversion_action_name = proto.Field( + proto.STRING, number=114, optional=True, + ) + conversion_adjustment = proto.Field(proto.BOOL, number=115, optional=True,) + conversion_attribution_event_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_conversion_attribution_event_type.ConversionAttributionEventTypeEnum.ConversionAttributionEventType, + ) + conversion_lag_bucket = proto.Field( + proto.ENUM, + number=50, + enum=gage_conversion_lag_bucket.ConversionLagBucketEnum.ConversionLagBucket, + ) + conversion_or_adjustment_lag_bucket = proto.Field( + proto.ENUM, + number=51, + enum=gage_conversion_or_adjustment_lag_bucket.ConversionOrAdjustmentLagBucketEnum.ConversionOrAdjustmentLagBucket, + ) + date = proto.Field(proto.STRING, number=79, optional=True,) + day_of_week = proto.Field( + proto.ENUM, number=5, enum=gage_day_of_week.DayOfWeekEnum.DayOfWeek, + ) + device = proto.Field( + proto.ENUM, number=1, enum=gage_device.DeviceEnum.Device, + ) + external_conversion_source = proto.Field( + proto.ENUM, + number=55, + enum=gage_external_conversion_source.ExternalConversionSourceEnum.ExternalConversionSource, + ) + geo_target_airport = proto.Field(proto.STRING, number=116, optional=True,) + geo_target_canton = proto.Field(proto.STRING, number=117, optional=True,) + geo_target_city = proto.Field(proto.STRING, number=118, optional=True,) + geo_target_country = proto.Field(proto.STRING, number=119, optional=True,) + geo_target_county = proto.Field(proto.STRING, number=120, optional=True,) + geo_target_district = proto.Field(proto.STRING, number=121, optional=True,) + geo_target_metro = proto.Field(proto.STRING, number=122, optional=True,) + geo_target_most_specific_location = proto.Field( + proto.STRING, number=123, optional=True, + ) + geo_target_postal_code = proto.Field( + proto.STRING, number=124, optional=True, + ) + geo_target_province = proto.Field(proto.STRING, number=125, optional=True,) + geo_target_region = proto.Field(proto.STRING, number=126, optional=True,) + geo_target_state = proto.Field(proto.STRING, number=127, optional=True,) + hotel_booking_window_days = proto.Field( + proto.INT64, number=135, optional=True, + ) + hotel_center_id = proto.Field(proto.INT64, number=80, optional=True,) + hotel_check_in_date = proto.Field(proto.STRING, number=81, optional=True,) + hotel_check_in_day_of_week = proto.Field( + proto.ENUM, number=9, enum=gage_day_of_week.DayOfWeekEnum.DayOfWeek, + ) + hotel_city = proto.Field(proto.STRING, number=82, optional=True,) + hotel_class = proto.Field(proto.INT32, number=83, optional=True,) + hotel_country = proto.Field(proto.STRING, number=84, optional=True,) + hotel_date_selection_type = proto.Field( + proto.ENUM, + number=13, + enum=gage_hotel_date_selection_type.HotelDateSelectionTypeEnum.HotelDateSelectionType, + ) + hotel_length_of_stay = proto.Field(proto.INT32, number=85, optional=True,) + hotel_rate_rule_id = proto.Field(proto.STRING, number=86, optional=True,) + hotel_rate_type = proto.Field( + proto.ENUM, + number=74, + enum=gage_hotel_rate_type.HotelRateTypeEnum.HotelRateType, + ) + hotel_price_bucket = proto.Field( + proto.ENUM, + number=78, + enum=gage_hotel_price_bucket.HotelPriceBucketEnum.HotelPriceBucket, + ) + hotel_state = proto.Field(proto.STRING, number=87, optional=True,) + hour = proto.Field(proto.INT32, number=88, optional=True,) + interaction_on_this_extension = proto.Field( + proto.BOOL, number=89, optional=True, + ) + keyword = proto.Field(proto.MESSAGE, number=61, message="Keyword",) + month = proto.Field(proto.STRING, number=90, optional=True,) + month_of_year = proto.Field( + proto.ENUM, + number=18, + enum=gage_month_of_year.MonthOfYearEnum.MonthOfYear, + ) + partner_hotel_id = proto.Field(proto.STRING, number=91, optional=True,) + placeholder_type = proto.Field( + proto.ENUM, + number=20, + enum=gage_placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + product_aggregator_id = proto.Field(proto.INT64, number=132, optional=True,) + product_bidding_category_level1 = proto.Field( + proto.STRING, number=92, optional=True, + ) + product_bidding_category_level2 = proto.Field( + proto.STRING, number=93, optional=True, + ) + product_bidding_category_level3 = proto.Field( + proto.STRING, number=94, optional=True, + ) + product_bidding_category_level4 = proto.Field( + proto.STRING, number=95, optional=True, + ) + product_bidding_category_level5 = proto.Field( + proto.STRING, number=96, optional=True, + ) + product_brand = proto.Field(proto.STRING, number=97, optional=True,) + product_channel = proto.Field( + proto.ENUM, + number=30, + enum=gage_product_channel.ProductChannelEnum.ProductChannel, + ) + product_channel_exclusivity = proto.Field( + proto.ENUM, + number=31, + enum=gage_product_channel_exclusivity.ProductChannelExclusivityEnum.ProductChannelExclusivity, + ) + product_condition = proto.Field( + proto.ENUM, + number=32, + enum=gage_product_condition.ProductConditionEnum.ProductCondition, + ) + product_country = proto.Field(proto.STRING, number=98, optional=True,) + product_custom_attribute0 = proto.Field( + proto.STRING, number=99, optional=True, + ) + product_custom_attribute1 = proto.Field( + proto.STRING, number=100, optional=True, + ) + product_custom_attribute2 = proto.Field( + proto.STRING, number=101, optional=True, + ) + product_custom_attribute3 = proto.Field( + proto.STRING, number=102, optional=True, + ) + product_custom_attribute4 = proto.Field( + proto.STRING, number=103, optional=True, + ) + product_item_id = proto.Field(proto.STRING, number=104, optional=True,) + product_language = proto.Field(proto.STRING, number=105, optional=True,) + product_merchant_id = proto.Field(proto.INT64, number=133, optional=True,) + product_store_id = proto.Field(proto.STRING, number=106, optional=True,) + product_title = proto.Field(proto.STRING, number=107, optional=True,) + product_type_l1 = proto.Field(proto.STRING, number=108, optional=True,) + product_type_l2 = proto.Field(proto.STRING, number=109, optional=True,) + product_type_l3 = proto.Field(proto.STRING, number=110, optional=True,) + product_type_l4 = proto.Field(proto.STRING, number=111, optional=True,) + product_type_l5 = proto.Field(proto.STRING, number=112, optional=True,) + quarter = proto.Field(proto.STRING, number=128, optional=True,) + recommendation_type = proto.Field( + proto.ENUM, + number=140, + enum=gage_recommendation_type.RecommendationTypeEnum.RecommendationType, + ) + search_engine_results_page_type = proto.Field( + proto.ENUM, + number=70, + enum=gage_search_engine_results_page_type.SearchEngineResultsPageTypeEnum.SearchEngineResultsPageType, + ) + search_term_match_type = proto.Field( + proto.ENUM, + number=22, + enum=gage_search_term_match_type.SearchTermMatchTypeEnum.SearchTermMatchType, + ) + slot = proto.Field(proto.ENUM, number=23, enum=gage_slot.SlotEnum.Slot,) + conversion_value_rule_primary_dimension = proto.Field( + proto.ENUM, + number=138, + enum=gage_conversion_value_rule_primary_dimension.ConversionValueRulePrimaryDimensionEnum.ConversionValueRulePrimaryDimension, + ) + webpage = proto.Field(proto.STRING, number=129, optional=True,) + week = proto.Field(proto.STRING, number=130, optional=True,) + year = proto.Field(proto.INT32, number=131, optional=True,) + sk_ad_network_conversion_value = proto.Field( + proto.INT64, number=137, optional=True, + ) + sk_ad_network_user_type = proto.Field( + proto.ENUM, + number=141, + enum=gage_sk_ad_network_user_type.SkAdNetworkUserTypeEnum.SkAdNetworkUserType, + ) + sk_ad_network_ad_event_type = proto.Field( + proto.ENUM, + number=142, + enum=gage_sk_ad_network_ad_event_type.SkAdNetworkAdEventTypeEnum.SkAdNetworkAdEventType, + ) + sk_ad_network_source_app = proto.Field( + proto.MESSAGE, + number=143, + optional=True, + message="SkAdNetworkSourceApp", + ) + sk_ad_network_attribution_credit = proto.Field( + proto.ENUM, + number=144, + enum=gage_sk_ad_network_attribution_credit.SkAdNetworkAttributionCreditEnum.SkAdNetworkAttributionCredit, + ) + asset_interaction_target = proto.Field( + proto.MESSAGE, + number=139, + optional=True, + message="AssetInteractionTarget", + ) + + +class Keyword(proto.Message): + r"""A Keyword criterion segment. + + Attributes: + ad_group_criterion (str): + The AdGroupCriterion resource name. + + This field is a member of `oneof`_ ``_ad_group_criterion``. + info (google.ads.googleads.v12.common.types.KeywordInfo): + Keyword info. + """ + + ad_group_criterion = proto.Field(proto.STRING, number=3, optional=True,) + info = proto.Field(proto.MESSAGE, number=2, message=criteria.KeywordInfo,) + + +class BudgetCampaignAssociationStatus(proto.Message): + r"""A BudgetCampaignAssociationStatus segment. + + Attributes: + campaign (str): + The campaign resource name. + + This field is a member of `oneof`_ ``_campaign``. + status (google.ads.googleads.v12.enums.types.BudgetCampaignAssociationStatusEnum.BudgetCampaignAssociationStatus): + Budget campaign association status. + """ + + campaign = proto.Field(proto.STRING, number=1, optional=True,) + status = proto.Field( + proto.ENUM, + number=2, + enum=gage_budget_campaign_association_status.BudgetCampaignAssociationStatusEnum.BudgetCampaignAssociationStatus, + ) + + +class AssetInteractionTarget(proto.Message): + r"""An AssetInteractionTarget segment. + + Attributes: + asset (str): + The asset resource name. + interaction_on_this_asset (bool): + Only used with CustomerAsset, CampaignAsset + and AdGroupAsset metrics. Indicates whether the + interaction metrics occurred on the asset itself + or a different asset or ad unit. + """ + + asset = proto.Field(proto.STRING, number=1,) + interaction_on_this_asset = proto.Field(proto.BOOL, number=2,) + + +class SkAdNetworkSourceApp(proto.Message): + r"""A SkAdNetworkSourceApp segment. + + Attributes: + sk_ad_network_source_app_id (str): + App id where the ad that drove the iOS Store + Kit Ad Network install was shown. + + This field is a member of `oneof`_ ``_sk_ad_network_source_app_id``. + """ + + sk_ad_network_source_app_id = proto.Field( + proto.STRING, number=1, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/simulation.py b/google/ads/googleads/v12/common/types/simulation.py new file mode 100644 index 000000000..1606e0f08 --- /dev/null +++ b/google/ads/googleads/v12/common/types/simulation.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "BidModifierSimulationPointList", + "CpcBidSimulationPointList", + "CpvBidSimulationPointList", + "TargetCpaSimulationPointList", + "TargetRoasSimulationPointList", + "PercentCpcBidSimulationPointList", + "BudgetSimulationPointList", + "TargetImpressionShareSimulationPointList", + "BidModifierSimulationPoint", + "CpcBidSimulationPoint", + "CpvBidSimulationPoint", + "TargetCpaSimulationPoint", + "TargetRoasSimulationPoint", + "PercentCpcBidSimulationPoint", + "BudgetSimulationPoint", + "TargetImpressionShareSimulationPoint", + }, +) + + +class BidModifierSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + BID_MODIFIER. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.BidModifierSimulationPoint]): + Projected metrics for a series of bid + modifier amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="BidModifierSimulationPoint", + ) + + +class CpcBidSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type CPC_BID. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.CpcBidSimulationPoint]): + Projected metrics for a series of CPC bid + amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="CpcBidSimulationPoint", + ) + + +class CpvBidSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type CPV_BID. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.CpvBidSimulationPoint]): + Projected metrics for a series of CPV bid + amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="CpvBidSimulationPoint", + ) + + +class TargetCpaSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + TARGET_CPA. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.TargetCpaSimulationPoint]): + Projected metrics for a series of target CPA + amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="TargetCpaSimulationPoint", + ) + + +class TargetRoasSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + TARGET_ROAS. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.TargetRoasSimulationPoint]): + Projected metrics for a series of target ROAS + amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="TargetRoasSimulationPoint", + ) + + +class PercentCpcBidSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + PERCENT_CPC_BID. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.PercentCpcBidSimulationPoint]): + Projected metrics for a series of percent CPC + bid amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="PercentCpcBidSimulationPoint", + ) + + +class BudgetSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + BUDGET. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.BudgetSimulationPoint]): + Projected metrics for a series of budget + amounts. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="BudgetSimulationPoint", + ) + + +class TargetImpressionShareSimulationPointList(proto.Message): + r"""A container for simulation points for simulations of type + TARGET_IMPRESSION_SHARE. + + Attributes: + points (Sequence[google.ads.googleads.v12.common.types.TargetImpressionShareSimulationPoint]): + Projected metrics for a specific target + impression share value. + """ + + points = proto.RepeatedField( + proto.MESSAGE, number=1, message="TargetImpressionShareSimulationPoint", + ) + + +class BidModifierSimulationPoint(proto.Message): + r"""Projected metrics for a specific bid modifier amount. + + Attributes: + bid_modifier (float): + The simulated bid modifier upon which + projected metrics are based. + + This field is a member of `oneof`_ ``_bid_modifier``. + biddable_conversions (float): + Projected number of biddable conversions. + Only search advertising channel type supports + this field. + + This field is a member of `oneof`_ ``_biddable_conversions``. + biddable_conversions_value (float): + Projected total value of biddable + conversions. Only search advertising channel + type supports this field. + + This field is a member of `oneof`_ ``_biddable_conversions_value``. + clicks (int): + Projected number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + top_slot_impressions (int): + Projected number of top slot impressions. + Only search advertising channel type supports + this field. + + This field is a member of `oneof`_ ``_top_slot_impressions``. + parent_biddable_conversions (float): + Projected number of biddable conversions for + the parent resource. Only search advertising + channel type supports this field. + + This field is a member of `oneof`_ ``_parent_biddable_conversions``. + parent_biddable_conversions_value (float): + Projected total value of biddable conversions + for the parent resource. Only search advertising + channel type supports this field. + + This field is a member of `oneof`_ ``_parent_biddable_conversions_value``. + parent_clicks (int): + Projected number of clicks for the parent + resource. + + This field is a member of `oneof`_ ``_parent_clicks``. + parent_cost_micros (int): + Projected cost in micros for the parent + resource. + + This field is a member of `oneof`_ ``_parent_cost_micros``. + parent_impressions (int): + Projected number of impressions for the + parent resource. + + This field is a member of `oneof`_ ``_parent_impressions``. + parent_top_slot_impressions (int): + Projected number of top slot impressions for + the parent resource. Only search advertising + channel type supports this field. + + This field is a member of `oneof`_ ``_parent_top_slot_impressions``. + parent_required_budget_micros (int): + Projected minimum daily budget that must be + available to the parent resource to realize this + simulation. + + This field is a member of `oneof`_ ``_parent_required_budget_micros``. + """ + + bid_modifier = proto.Field(proto.DOUBLE, number=15, optional=True,) + biddable_conversions = proto.Field(proto.DOUBLE, number=16, optional=True,) + biddable_conversions_value = proto.Field( + proto.DOUBLE, number=17, optional=True, + ) + clicks = proto.Field(proto.INT64, number=18, optional=True,) + cost_micros = proto.Field(proto.INT64, number=19, optional=True,) + impressions = proto.Field(proto.INT64, number=20, optional=True,) + top_slot_impressions = proto.Field(proto.INT64, number=21, optional=True,) + parent_biddable_conversions = proto.Field( + proto.DOUBLE, number=22, optional=True, + ) + parent_biddable_conversions_value = proto.Field( + proto.DOUBLE, number=23, optional=True, + ) + parent_clicks = proto.Field(proto.INT64, number=24, optional=True,) + parent_cost_micros = proto.Field(proto.INT64, number=25, optional=True,) + parent_impressions = proto.Field(proto.INT64, number=26, optional=True,) + parent_top_slot_impressions = proto.Field( + proto.INT64, number=27, optional=True, + ) + parent_required_budget_micros = proto.Field( + proto.INT64, number=28, optional=True, + ) + + +class CpcBidSimulationPoint(proto.Message): + r"""Projected metrics for a specific CPC bid amount. + + 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: + required_budget_amount_micros (int): + Projected required daily budget that the + advertiser must set in order to receive the + estimated traffic, in micros of advertiser + currency. + biddable_conversions (float): + Projected number of biddable conversions. + + This field is a member of `oneof`_ ``_biddable_conversions``. + biddable_conversions_value (float): + Projected total value of biddable + conversions. + + This field is a member of `oneof`_ ``_biddable_conversions_value``. + clicks (int): + Projected number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + top_slot_impressions (int): + Projected number of top slot impressions. + Only search advertising channel type supports + this field. + + This field is a member of `oneof`_ ``_top_slot_impressions``. + cpc_bid_micros (int): + The simulated CPC bid upon which projected + metrics are based. + + This field is a member of `oneof`_ ``cpc_simulation_key_value``. + cpc_bid_scaling_modifier (float): + The simulated scaling modifier upon which + projected metrics are based. All CPC bids + relevant to the simulated entity are scaled by + this modifier. + + This field is a member of `oneof`_ ``cpc_simulation_key_value``. + """ + + required_budget_amount_micros = proto.Field(proto.INT64, number=17,) + biddable_conversions = proto.Field(proto.DOUBLE, number=9, optional=True,) + biddable_conversions_value = proto.Field( + proto.DOUBLE, number=10, optional=True, + ) + clicks = proto.Field(proto.INT64, number=11, optional=True,) + cost_micros = proto.Field(proto.INT64, number=12, optional=True,) + impressions = proto.Field(proto.INT64, number=13, optional=True,) + top_slot_impressions = proto.Field(proto.INT64, number=14, optional=True,) + cpc_bid_micros = proto.Field( + proto.INT64, number=15, oneof="cpc_simulation_key_value", + ) + cpc_bid_scaling_modifier = proto.Field( + proto.DOUBLE, number=16, oneof="cpc_simulation_key_value", + ) + + +class CpvBidSimulationPoint(proto.Message): + r"""Projected metrics for a specific CPV bid amount. + + Attributes: + cpv_bid_micros (int): + The simulated CPV bid upon which projected + metrics are based. + + This field is a member of `oneof`_ ``_cpv_bid_micros``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + views (int): + Projected number of views. + + This field is a member of `oneof`_ ``_views``. + """ + + cpv_bid_micros = proto.Field(proto.INT64, number=5, optional=True,) + cost_micros = proto.Field(proto.INT64, number=6, optional=True,) + impressions = proto.Field(proto.INT64, number=7, optional=True,) + views = proto.Field(proto.INT64, number=8, optional=True,) + + +class TargetCpaSimulationPoint(proto.Message): + r"""Projected metrics for a specific target CPA amount. + + 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: + required_budget_amount_micros (int): + Projected required daily budget that the + advertiser must set in order to receive the + estimated traffic, in micros of advertiser + currency. + biddable_conversions (float): + Projected number of biddable conversions. + + This field is a member of `oneof`_ ``_biddable_conversions``. + biddable_conversions_value (float): + Projected total value of biddable + conversions. + + This field is a member of `oneof`_ ``_biddable_conversions_value``. + app_installs (float): + Projected number of app installs. + in_app_actions (float): + Projected number of in-app actions. + clicks (int): + Projected number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + top_slot_impressions (int): + Projected number of top slot impressions. + Only search advertising channel type supports + this field. + + This field is a member of `oneof`_ ``_top_slot_impressions``. + target_cpa_micros (int): + The simulated target CPA upon which projected + metrics are based. + + This field is a member of `oneof`_ ``target_cpa_simulation_key_value``. + target_cpa_scaling_modifier (float): + The simulated scaling modifier upon which + projected metrics are based. All CPA targets + relevant to the simulated entity are scaled by + this modifier. + + This field is a member of `oneof`_ ``target_cpa_simulation_key_value``. + """ + + required_budget_amount_micros = proto.Field(proto.INT64, number=19,) + biddable_conversions = proto.Field(proto.DOUBLE, number=9, optional=True,) + biddable_conversions_value = proto.Field( + proto.DOUBLE, number=10, optional=True, + ) + app_installs = proto.Field(proto.DOUBLE, number=15,) + in_app_actions = proto.Field(proto.DOUBLE, number=16,) + clicks = proto.Field(proto.INT64, number=11, optional=True,) + cost_micros = proto.Field(proto.INT64, number=12, optional=True,) + impressions = proto.Field(proto.INT64, number=13, optional=True,) + top_slot_impressions = proto.Field(proto.INT64, number=14, optional=True,) + target_cpa_micros = proto.Field( + proto.INT64, number=17, oneof="target_cpa_simulation_key_value", + ) + target_cpa_scaling_modifier = proto.Field( + proto.DOUBLE, number=18, oneof="target_cpa_simulation_key_value", + ) + + +class TargetRoasSimulationPoint(proto.Message): + r"""Projected metrics for a specific target ROAS amount. + + Attributes: + target_roas (float): + The simulated target ROAS upon which + projected metrics are based. + + This field is a member of `oneof`_ ``_target_roas``. + required_budget_amount_micros (int): + Projected required daily budget that the + advertiser must set in order to receive the + estimated traffic, in micros of advertiser + currency. + biddable_conversions (float): + Projected number of biddable conversions. + + This field is a member of `oneof`_ ``_biddable_conversions``. + biddable_conversions_value (float): + Projected total value of biddable + conversions. + + This field is a member of `oneof`_ ``_biddable_conversions_value``. + clicks (int): + Projected number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + top_slot_impressions (int): + Projected number of top slot impressions. + Only Search advertising channel type supports + this field. + + This field is a member of `oneof`_ ``_top_slot_impressions``. + """ + + target_roas = proto.Field(proto.DOUBLE, number=8, optional=True,) + required_budget_amount_micros = proto.Field(proto.INT64, number=15,) + biddable_conversions = proto.Field(proto.DOUBLE, number=9, optional=True,) + biddable_conversions_value = proto.Field( + proto.DOUBLE, number=10, optional=True, + ) + clicks = proto.Field(proto.INT64, number=11, optional=True,) + cost_micros = proto.Field(proto.INT64, number=12, optional=True,) + impressions = proto.Field(proto.INT64, number=13, optional=True,) + top_slot_impressions = proto.Field(proto.INT64, number=14, optional=True,) + + +class PercentCpcBidSimulationPoint(proto.Message): + r"""Projected metrics for a specific percent CPC amount. Only + Hotel advertising channel type supports this field. + + Attributes: + percent_cpc_bid_micros (int): + The simulated percent CPC upon which projected metrics are + based. Percent CPC expressed as fraction of the advertised + price for some good or service. The value stored here is + 1,000,000 \* [fraction]. + + This field is a member of `oneof`_ ``_percent_cpc_bid_micros``. + biddable_conversions (float): + Projected number of biddable conversions. + + This field is a member of `oneof`_ ``_biddable_conversions``. + biddable_conversions_value (float): + Projected total value of biddable conversions + in local currency. + + This field is a member of `oneof`_ ``_biddable_conversions_value``. + clicks (int): + Projected number of clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Projected cost in micros. + + This field is a member of `oneof`_ ``_cost_micros``. + impressions (int): + Projected number of impressions. + + This field is a member of `oneof`_ ``_impressions``. + top_slot_impressions (int): + Projected number of top slot impressions. + + This field is a member of `oneof`_ ``_top_slot_impressions``. + """ + + percent_cpc_bid_micros = proto.Field(proto.INT64, number=1, optional=True,) + biddable_conversions = proto.Field(proto.DOUBLE, number=2, optional=True,) + biddable_conversions_value = proto.Field( + proto.DOUBLE, number=3, optional=True, + ) + clicks = proto.Field(proto.INT64, number=4, optional=True,) + cost_micros = proto.Field(proto.INT64, number=5, optional=True,) + impressions = proto.Field(proto.INT64, number=6, optional=True,) + top_slot_impressions = proto.Field(proto.INT64, number=7, optional=True,) + + +class BudgetSimulationPoint(proto.Message): + r"""Projected metrics for a specific budget amount. + + Attributes: + budget_amount_micros (int): + The simulated budget upon which projected + metrics are based. + required_cpc_bid_ceiling_micros (int): + Projected required daily cpc bid ceiling that + the advertiser must set to realize this + simulation, in micros of the advertiser + currency. Only campaigns with the Target Spend + bidding strategy support this field. + biddable_conversions (float): + Projected number of biddable conversions. + biddable_conversions_value (float): + Projected total value of biddable + conversions. + clicks (int): + Projected number of clicks. + cost_micros (int): + Projected cost in micros. + impressions (int): + Projected number of impressions. + top_slot_impressions (int): + Projected number of top slot impressions. + Only search advertising channel type supports + this field. + """ + + budget_amount_micros = proto.Field(proto.INT64, number=1,) + required_cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=2,) + biddable_conversions = proto.Field(proto.DOUBLE, number=3,) + biddable_conversions_value = proto.Field(proto.DOUBLE, number=4,) + clicks = proto.Field(proto.INT64, number=5,) + cost_micros = proto.Field(proto.INT64, number=6,) + impressions = proto.Field(proto.INT64, number=7,) + top_slot_impressions = proto.Field(proto.INT64, number=8,) + + +class TargetImpressionShareSimulationPoint(proto.Message): + r"""Projected metrics for a specific target impression share + value. + + Attributes: + target_impression_share_micros (int): + The simulated target impression share value (in micros) upon + which projected metrics are based. For example, 10% + impression share, which is equal to 0.1, is stored as + 100_000. This value is validated and will not exceed 1M + (100%). + required_cpc_bid_ceiling_micros (int): + Projected required daily cpc bid ceiling that + the advertiser must set to realize this + simulation, in micros of the advertiser + currency. + required_budget_amount_micros (int): + Projected required daily budget that the + advertiser must set in order to receive the + estimated traffic, in micros of advertiser + currency. + biddable_conversions (float): + Projected number of biddable conversions. + biddable_conversions_value (float): + Projected total value of biddable + conversions. + clicks (int): + Projected number of clicks. + cost_micros (int): + Projected cost in micros. + impressions (int): + Projected number of impressions. + top_slot_impressions (int): + Projected number of top slot impressions. + Only search advertising channel type supports + this field. + absolute_top_impressions (int): + Projected number of absolute top impressions. + Only search advertising channel type supports + this field. + """ + + target_impression_share_micros = proto.Field(proto.INT64, number=1,) + required_cpc_bid_ceiling_micros = proto.Field(proto.INT64, number=2,) + required_budget_amount_micros = proto.Field(proto.INT64, number=3,) + biddable_conversions = proto.Field(proto.DOUBLE, number=4,) + biddable_conversions_value = proto.Field(proto.DOUBLE, number=5,) + clicks = proto.Field(proto.INT64, number=6,) + cost_micros = proto.Field(proto.INT64, number=7,) + impressions = proto.Field(proto.INT64, number=8,) + top_slot_impressions = proto.Field(proto.INT64, number=9,) + absolute_top_impressions = proto.Field(proto.INT64, number=10,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/tag_snippet.py b/google/ads/googleads/v12/common/types/tag_snippet.py new file mode 100644 index 000000000..7c1d0f12d --- /dev/null +++ b/google/ads/googleads/v12/common/types/tag_snippet.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import tracking_code_page_format +from google.ads.googleads.v12.enums.types import tracking_code_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"TagSnippet",}, +) + + +class TagSnippet(proto.Message): + r"""The site tag and event snippet pair for a TrackingCodeType. + + Attributes: + type_ (google.ads.googleads.v12.enums.types.TrackingCodeTypeEnum.TrackingCodeType): + The type of the generated tag snippets for + tracking conversions. + page_format (google.ads.googleads.v12.enums.types.TrackingCodePageFormatEnum.TrackingCodePageFormat): + The format of the web page where the tracking + tag and snippet will be installed, for example, + HTML. + global_site_tag (str): + The site tag that adds visitors to your basic + remarketing lists and sets new cookies on your + domain. + + This field is a member of `oneof`_ ``_global_site_tag``. + event_snippet (str): + The event snippet that works with the site + tag to track actions that should be counted as + conversions. + + This field is a member of `oneof`_ ``_event_snippet``. + """ + + type_ = proto.Field( + proto.ENUM, + number=1, + enum=tracking_code_type.TrackingCodeTypeEnum.TrackingCodeType, + ) + page_format = proto.Field( + proto.ENUM, + number=2, + enum=tracking_code_page_format.TrackingCodePageFormatEnum.TrackingCodePageFormat, + ) + global_site_tag = proto.Field(proto.STRING, number=5, optional=True,) + event_snippet = proto.Field(proto.STRING, number=6, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/targeting_setting.py b/google/ads/googleads/v12/common/types/targeting_setting.py new file mode 100644 index 000000000..016d85a02 --- /dev/null +++ b/google/ads/googleads/v12/common/types/targeting_setting.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + targeting_dimension as gage_targeting_dimension, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "TargetingSetting", + "TargetRestriction", + "TargetRestrictionOperation", + }, +) + + +class TargetingSetting(proto.Message): + r"""Settings for the targeting-related features, at the campaign + and ad group levels. For more details about the targeting + setting, visit + https://support.google.com/google-ads/answer/7365594 + + Attributes: + target_restrictions (Sequence[google.ads.googleads.v12.common.types.TargetRestriction]): + The per-targeting-dimension setting to + restrict the reach of your campaign or ad group. + target_restriction_operations (Sequence[google.ads.googleads.v12.common.types.TargetRestrictionOperation]): + The list of operations changing the target + restrictions. + Adding a target restriction with a targeting + dimension that already exists causes the + existing target restriction to be replaced with + the new value. + """ + + target_restrictions = proto.RepeatedField( + proto.MESSAGE, number=1, message="TargetRestriction", + ) + target_restriction_operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="TargetRestrictionOperation", + ) + + +class TargetRestriction(proto.Message): + r"""The list of per-targeting-dimension targeting settings. + + Attributes: + targeting_dimension (google.ads.googleads.v12.enums.types.TargetingDimensionEnum.TargetingDimension): + The targeting dimension that these settings + apply to. + bid_only (bool): + Indicates whether to restrict your ads to show only for the + criteria you have selected for this targeting_dimension, or + to target all values for this targeting_dimension and show + ads based on your targeting in other TargetingDimensions. A + value of ``true`` means that these criteria will only apply + bid modifiers, and not affect targeting. A value of + ``false`` means that these criteria will restrict targeting + as well as applying bid modifiers. + + This field is a member of `oneof`_ ``_bid_only``. + """ + + targeting_dimension = proto.Field( + proto.ENUM, + number=1, + enum=gage_targeting_dimension.TargetingDimensionEnum.TargetingDimension, + ) + bid_only = proto.Field(proto.BOOL, number=3, optional=True,) + + +class TargetRestrictionOperation(proto.Message): + r"""Operation to be performed on a target restriction list in a + mutate. + + Attributes: + operator (google.ads.googleads.v12.common.types.TargetRestrictionOperation.Operator): + Type of list operation to perform. + value (google.ads.googleads.v12.common.types.TargetRestriction): + The target restriction being added to or + removed from the list. + """ + + class Operator(proto.Enum): + r"""The operator.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADD = 2 + REMOVE = 3 + + operator = proto.Field(proto.ENUM, number=1, enum=Operator,) + value = proto.Field(proto.MESSAGE, number=2, message="TargetRestriction",) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/text_label.py b/google/ads/googleads/v12/common/types/text_label.py new file mode 100644 index 000000000..c2362e190 --- /dev/null +++ b/google/ads/googleads/v12/common/types/text_label.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"TextLabel",}, +) + + +class TextLabel(proto.Message): + r"""A type of label displaying text on a colored background. + + Attributes: + background_color (str): + Background color of the label in RGB format. This string + must match the regular expression + '^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$'. Note: The background + color may not be visible for manager accounts. + + This field is a member of `oneof`_ ``_background_color``. + description (str): + A short description of the label. The length + must be no more than 200 characters. + + This field is a member of `oneof`_ ``_description``. + """ + + background_color = proto.Field(proto.STRING, number=3, optional=True,) + description = proto.Field(proto.STRING, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/url_collection.py b/google/ads/googleads/v12/common/types/url_collection.py new file mode 100644 index 000000000..dc4720562 --- /dev/null +++ b/google/ads/googleads/v12/common/types/url_collection.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"UrlCollection",}, +) + + +class UrlCollection(proto.Message): + r"""Collection of urls that is tagged with a unique identifier. + + Attributes: + url_collection_id (str): + Unique identifier for this UrlCollection + instance. + + This field is a member of `oneof`_ ``_url_collection_id``. + final_urls (Sequence[str]): + A list of possible final URLs. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs. + tracking_url_template (str): + URL template for constructing a tracking URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + """ + + url_collection_id = proto.Field(proto.STRING, number=5, optional=True,) + final_urls = proto.RepeatedField(proto.STRING, number=6,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=7,) + tracking_url_template = proto.Field(proto.STRING, number=8, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/user_lists.py b/google/ads/googleads/v12/common/types/user_lists.py new file mode 100644 index 000000000..4e344148a --- /dev/null +++ b/google/ads/googleads/v12/common/types/user_lists.py @@ -0,0 +1,576 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import customer_match_upload_key_type +from google.ads.googleads.v12.enums.types import ( + user_list_combined_rule_operator, +) +from google.ads.googleads.v12.enums.types import user_list_crm_data_source_type +from google.ads.googleads.v12.enums.types import ( + user_list_date_rule_item_operator, +) +from google.ads.googleads.v12.enums.types import ( + user_list_flexible_rule_operator, +) +from google.ads.googleads.v12.enums.types import user_list_logical_rule_operator +from google.ads.googleads.v12.enums.types import ( + user_list_number_rule_item_operator, +) +from google.ads.googleads.v12.enums.types import user_list_prepopulation_status +from google.ads.googleads.v12.enums.types import user_list_rule_type +from google.ads.googleads.v12.enums.types import ( + user_list_string_rule_item_operator, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={ + "SimilarUserListInfo", + "CrmBasedUserListInfo", + "UserListRuleInfo", + "UserListRuleItemGroupInfo", + "UserListRuleItemInfo", + "UserListDateRuleItemInfo", + "UserListNumberRuleItemInfo", + "UserListStringRuleItemInfo", + "CombinedRuleUserListInfo", + "ExpressionRuleUserListInfo", + "FlexibleRuleOperandInfo", + "FlexibleRuleUserListInfo", + "RuleBasedUserListInfo", + "LogicalUserListInfo", + "UserListLogicalRuleInfo", + "LogicalUserListOperandInfo", + "BasicUserListInfo", + "UserListActionInfo", + }, +) + + +class SimilarUserListInfo(proto.Message): + r"""SimilarUserList is a list of users which are similar to users + from another UserList. These lists are read-only and + automatically created by Google. + + Attributes: + seed_user_list (str): + Seed UserList from which this list is + derived. + + This field is a member of `oneof`_ ``_seed_user_list``. + """ + + seed_user_list = proto.Field(proto.STRING, number=2, optional=True,) + + +class CrmBasedUserListInfo(proto.Message): + r"""UserList of CRM users provided by the advertiser. + + Attributes: + app_id (str): + A string that uniquely identifies a mobile + application from which the data was collected. + For iOS, the ID string is the 9 digit string + that appears at the end of an App Store URL (for + example, "476943146" for "Flood-It! 2" whose App + Store link is + http://itunes.apple.com/us/app/flood-it!-2/id476943146). + For Android, the ID string is the application's + package name (for example, + "com.labpixies.colordrips" for "Color Drips" + given Google Play link + https://play.google.com/store/apps/details?id=com.labpixies.colordrips). + Required when creating CrmBasedUserList for + uploading mobile advertising IDs. + + This field is a member of `oneof`_ ``_app_id``. + upload_key_type (google.ads.googleads.v12.enums.types.CustomerMatchUploadKeyTypeEnum.CustomerMatchUploadKeyType): + Matching key type of the list. + Mixed data types are not allowed on the same + list. This field is required for an ADD + operation. + data_source_type (google.ads.googleads.v12.enums.types.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType): + Data source of the list. Default value is FIRST_PARTY. Only + customers on the allow-list can create third-party sourced + CRM lists. + """ + + app_id = proto.Field(proto.STRING, number=4, optional=True,) + upload_key_type = proto.Field( + proto.ENUM, + number=2, + enum=customer_match_upload_key_type.CustomerMatchUploadKeyTypeEnum.CustomerMatchUploadKeyType, + ) + data_source_type = proto.Field( + proto.ENUM, + number=3, + enum=user_list_crm_data_source_type.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType, + ) + + +class UserListRuleInfo(proto.Message): + r"""A client defined rule based on custom parameters sent by web + sites or uploaded by the advertiser. + + Attributes: + rule_type (google.ads.googleads.v12.enums.types.UserListRuleTypeEnum.UserListRuleType): + Rule type is used to determine how to group + rule items. + The default is OR of ANDs (disjunctive normal + form). That is, rule items will be ANDed + together within rule item groups and the groups + themselves will be ORed together. + + Currently AND of ORs (conjunctive normal form) + is only supported for ExpressionRuleUserList. + rule_item_groups (Sequence[google.ads.googleads.v12.common.types.UserListRuleItemGroupInfo]): + List of rule item groups that defines this rule. Rule item + groups are grouped together based on rule_type. + """ + + rule_type = proto.Field( + proto.ENUM, + number=1, + enum=user_list_rule_type.UserListRuleTypeEnum.UserListRuleType, + ) + rule_item_groups = proto.RepeatedField( + proto.MESSAGE, number=2, message="UserListRuleItemGroupInfo", + ) + + +class UserListRuleItemGroupInfo(proto.Message): + r"""A group of rule items. + + Attributes: + rule_items (Sequence[google.ads.googleads.v12.common.types.UserListRuleItemInfo]): + Rule items that will be grouped together based on rule_type. + """ + + rule_items = proto.RepeatedField( + proto.MESSAGE, number=1, message="UserListRuleItemInfo", + ) + + +class UserListRuleItemInfo(proto.Message): + r"""An atomic rule item. + + 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): + Rule variable name. It should match the corresponding key + name fired by the pixel. A name must begin with US-ascii + letters or underscore or UTF8 code that is greater than 127 + and consist of US-ascii letters or digits or underscore or + UTF8 code that is greater than 127. For websites, there are + two built-in variable URL (name = 'url__') and referrer URL + (name = 'ref_url__'). This field must be populated when + creating a new rule item. + + This field is a member of `oneof`_ ``_name``. + number_rule_item (google.ads.googleads.v12.common.types.UserListNumberRuleItemInfo): + An atomic rule item composed of a number + operation. + + This field is a member of `oneof`_ ``rule_item``. + string_rule_item (google.ads.googleads.v12.common.types.UserListStringRuleItemInfo): + An atomic rule item composed of a string + operation. + + This field is a member of `oneof`_ ``rule_item``. + date_rule_item (google.ads.googleads.v12.common.types.UserListDateRuleItemInfo): + An atomic rule item composed of a date + operation. + + This field is a member of `oneof`_ ``rule_item``. + """ + + name = proto.Field(proto.STRING, number=5, optional=True,) + number_rule_item = proto.Field( + proto.MESSAGE, + number=2, + oneof="rule_item", + message="UserListNumberRuleItemInfo", + ) + string_rule_item = proto.Field( + proto.MESSAGE, + number=3, + oneof="rule_item", + message="UserListStringRuleItemInfo", + ) + date_rule_item = proto.Field( + proto.MESSAGE, + number=4, + oneof="rule_item", + message="UserListDateRuleItemInfo", + ) + + +class UserListDateRuleItemInfo(proto.Message): + r"""A rule item composed of a date operation. + + Attributes: + operator (google.ads.googleads.v12.enums.types.UserListDateRuleItemOperatorEnum.UserListDateRuleItemOperator): + Date comparison operator. + This field is required and must be populated + when creating new date rule item. + value (str): + String representing date value to be compared + with the rule variable. Supported date format is + YYYY-MM-DD. Times are reported in the customer's + time zone. + + This field is a member of `oneof`_ ``_value``. + offset_in_days (int): + The relative date value of the right hand + side denoted by number of days offset from now. + The value field will override this field when + both are present. + + This field is a member of `oneof`_ ``_offset_in_days``. + """ + + operator = proto.Field( + proto.ENUM, + number=1, + enum=user_list_date_rule_item_operator.UserListDateRuleItemOperatorEnum.UserListDateRuleItemOperator, + ) + value = proto.Field(proto.STRING, number=4, optional=True,) + offset_in_days = proto.Field(proto.INT64, number=5, optional=True,) + + +class UserListNumberRuleItemInfo(proto.Message): + r"""A rule item composed of a number operation. + + Attributes: + operator (google.ads.googleads.v12.enums.types.UserListNumberRuleItemOperatorEnum.UserListNumberRuleItemOperator): + Number comparison operator. + This field is required and must be populated + when creating a new number rule item. + value (float): + Number value to be compared with the + variable. This field is required and must be + populated when creating a new number rule item. + + This field is a member of `oneof`_ ``_value``. + """ + + operator = proto.Field( + proto.ENUM, + number=1, + enum=user_list_number_rule_item_operator.UserListNumberRuleItemOperatorEnum.UserListNumberRuleItemOperator, + ) + value = proto.Field(proto.DOUBLE, number=3, optional=True,) + + +class UserListStringRuleItemInfo(proto.Message): + r"""A rule item composed of a string operation. + + Attributes: + operator (google.ads.googleads.v12.enums.types.UserListStringRuleItemOperatorEnum.UserListStringRuleItemOperator): + String comparison operator. + This field is required and must be populated + when creating a new string rule item. + value (str): + The right hand side of the string rule item. + For URLs or referrer URLs, the value can not + contain illegal URL chars such as newlines, + quotes, tabs, or parentheses. This field is + required and must be populated when creating a + new string rule item. + + This field is a member of `oneof`_ ``_value``. + """ + + operator = proto.Field( + proto.ENUM, + number=1, + enum=user_list_string_rule_item_operator.UserListStringRuleItemOperatorEnum.UserListStringRuleItemOperator, + ) + value = proto.Field(proto.STRING, number=3, optional=True,) + + +class CombinedRuleUserListInfo(proto.Message): + r"""User lists defined by combining two rules, left operand and right + operand. There are two operators: AND where left operand and right + operand have to be true; AND_NOT where left operand is true but + right operand is false. + + Attributes: + left_operand (google.ads.googleads.v12.common.types.UserListRuleInfo): + Left operand of the combined rule. + This field is required and must be populated + when creating new combined rule based user list. + right_operand (google.ads.googleads.v12.common.types.UserListRuleInfo): + Right operand of the combined rule. + This field is required and must be populated + when creating new combined rule based user list. + rule_operator (google.ads.googleads.v12.enums.types.UserListCombinedRuleOperatorEnum.UserListCombinedRuleOperator): + Operator to connect the two operands. + Required for creating a combined rule user list. + """ + + left_operand = proto.Field( + proto.MESSAGE, number=1, message="UserListRuleInfo", + ) + right_operand = proto.Field( + proto.MESSAGE, number=2, message="UserListRuleInfo", + ) + rule_operator = proto.Field( + proto.ENUM, + number=3, + enum=user_list_combined_rule_operator.UserListCombinedRuleOperatorEnum.UserListCombinedRuleOperator, + ) + + +class ExpressionRuleUserListInfo(proto.Message): + r"""Visitors of a page. The page visit is defined by one boolean + rule expression. + + Attributes: + rule (google.ads.googleads.v12.common.types.UserListRuleInfo): + Boolean rule that defines this user list. The rule consists + of a list of rule item groups and each rule item group + consists of a list of rule items. All the rule item groups + are ORed or ANDed together for evaluation based on + rule.rule_type. + + Required for creating an expression rule user list. + """ + + rule = proto.Field(proto.MESSAGE, number=1, message="UserListRuleInfo",) + + +class FlexibleRuleOperandInfo(proto.Message): + r"""Flexible rule that wraps the common rule and a lookback + window. + + Attributes: + rule (google.ads.googleads.v12.common.types.UserListRuleInfo): + List of rule item groups that defines this + rule. Rule item groups are grouped together. + lookback_window_days (int): + Lookback window for this rule in days. From + now until X days ago. + + This field is a member of `oneof`_ ``_lookback_window_days``. + """ + + rule = proto.Field(proto.MESSAGE, number=1, message="UserListRuleInfo",) + lookback_window_days = proto.Field(proto.INT64, number=2, optional=True,) + + +class FlexibleRuleUserListInfo(proto.Message): + r"""Flexible rule representation of visitors with one or multiple + actions. + + Attributes: + inclusive_rule_operator (google.ads.googleads.v12.enums.types.UserListFlexibleRuleOperatorEnum.UserListFlexibleRuleOperator): + Operator that defines how the inclusive + operands are combined. + inclusive_operands (Sequence[google.ads.googleads.v12.common.types.FlexibleRuleOperandInfo]): + Actions that are located on the inclusive side. These are + joined together by either AND/OR as specified by the + inclusive_rule_operator. + exclusive_operands (Sequence[google.ads.googleads.v12.common.types.FlexibleRuleOperandInfo]): + Actions that are located on the exclusive + side. These are joined together with OR. + """ + + inclusive_rule_operator = proto.Field( + proto.ENUM, + number=1, + enum=user_list_flexible_rule_operator.UserListFlexibleRuleOperatorEnum.UserListFlexibleRuleOperator, + ) + inclusive_operands = proto.RepeatedField( + proto.MESSAGE, number=2, message="FlexibleRuleOperandInfo", + ) + exclusive_operands = proto.RepeatedField( + proto.MESSAGE, number=3, message="FlexibleRuleOperandInfo", + ) + + +class RuleBasedUserListInfo(proto.Message): + r"""Representation of a userlist that is generated by a rule. + + 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: + prepopulation_status (google.ads.googleads.v12.enums.types.UserListPrepopulationStatusEnum.UserListPrepopulationStatus): + The status of pre-population. The field is + default to NONE if not set which means the + previous users will not be considered. If set to + REQUESTED, past site visitors or app users who + match the list definition will be included in + the list (works on the Display Network only). + This will only add past users from within the + last 30 days, depending on the list's membership + duration and the date when the remarketing tag + is added. The status will be updated to FINISHED + once request is processed, or FAILED if the + request fails. + flexible_rule_user_list (google.ads.googleads.v12.common.types.FlexibleRuleUserListInfo): + Flexible rule representation of visitors with + one or multiple actions. + combined_rule_user_list (google.ads.googleads.v12.common.types.CombinedRuleUserListInfo): + User lists defined by combining two rules. There are two + operators: AND, where the left and right operands have to be + true; AND_NOT where left operand is true but right operand + is false. + + This field is a member of `oneof`_ ``rule_based_user_list``. + expression_rule_user_list (google.ads.googleads.v12.common.types.ExpressionRuleUserListInfo): + Visitors of a page. The page visit is defined + by one boolean rule expression. + + This field is a member of `oneof`_ ``rule_based_user_list``. + """ + + prepopulation_status = proto.Field( + proto.ENUM, + number=1, + enum=user_list_prepopulation_status.UserListPrepopulationStatusEnum.UserListPrepopulationStatus, + ) + flexible_rule_user_list = proto.Field( + proto.MESSAGE, number=5, message="FlexibleRuleUserListInfo", + ) + combined_rule_user_list = proto.Field( + proto.MESSAGE, + number=2, + oneof="rule_based_user_list", + message="CombinedRuleUserListInfo", + ) + expression_rule_user_list = proto.Field( + proto.MESSAGE, + number=4, + oneof="rule_based_user_list", + message="ExpressionRuleUserListInfo", + ) + + +class LogicalUserListInfo(proto.Message): + r"""Represents a user list that is a custom combination of user + lists. + + Attributes: + rules (Sequence[google.ads.googleads.v12.common.types.UserListLogicalRuleInfo]): + Logical list rules that define this user + list. The rules are defined as a logical + operator (ALL/ANY/NONE) and a list of user + lists. All the rules are ANDed when they are + evaluated. + + Required for creating a logical user list. + """ + + rules = proto.RepeatedField( + proto.MESSAGE, number=1, message="UserListLogicalRuleInfo", + ) + + +class UserListLogicalRuleInfo(proto.Message): + r"""A user list logical rule. A rule has a logical operator + (and/or/not) and a list of user lists as operands. + + Attributes: + operator (google.ads.googleads.v12.enums.types.UserListLogicalRuleOperatorEnum.UserListLogicalRuleOperator): + The logical operator of the rule. + rule_operands (Sequence[google.ads.googleads.v12.common.types.LogicalUserListOperandInfo]): + The list of operands of the rule. + """ + + operator = proto.Field( + proto.ENUM, + number=1, + enum=user_list_logical_rule_operator.UserListLogicalRuleOperatorEnum.UserListLogicalRuleOperator, + ) + rule_operands = proto.RepeatedField( + proto.MESSAGE, number=2, message="LogicalUserListOperandInfo", + ) + + +class LogicalUserListOperandInfo(proto.Message): + r"""Operand of logical user list that consists of a user list. + + Attributes: + user_list (str): + Resource name of a user list as an operand. + + This field is a member of `oneof`_ ``_user_list``. + """ + + user_list = proto.Field(proto.STRING, number=2, optional=True,) + + +class BasicUserListInfo(proto.Message): + r"""User list targeting as a collection of conversions or + remarketing actions. + + Attributes: + actions (Sequence[google.ads.googleads.v12.common.types.UserListActionInfo]): + Actions associated with this user list. + """ + + actions = proto.RepeatedField( + proto.MESSAGE, number=1, message="UserListActionInfo", + ) + + +class UserListActionInfo(proto.Message): + r"""Represents an action type used for building remarketing user + lists. + + 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: + conversion_action (str): + A conversion action that's not generated from + remarketing. + + This field is a member of `oneof`_ ``user_list_action``. + remarketing_action (str): + A remarketing action. + + This field is a member of `oneof`_ ``user_list_action``. + """ + + conversion_action = proto.Field( + proto.STRING, number=3, oneof="user_list_action", + ) + remarketing_action = proto.Field( + proto.STRING, number=4, oneof="user_list_action", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/common/types/value.py b/google/ads/googleads/v12/common/types/value.py new file mode 100644 index 000000000..76db437ab --- /dev/null +++ b/google/ads/googleads/v12/common/types/value.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.common", + marshal="google.ads.googleads.v12", + manifest={"Value",}, +) + + +class Value(proto.Message): + r"""A generic data container. + + 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: + boolean_value (bool): + A boolean. + + This field is a member of `oneof`_ ``value``. + int64_value (int): + An int64. + + This field is a member of `oneof`_ ``value``. + float_value (float): + A float. + + This field is a member of `oneof`_ ``value``. + double_value (float): + A double. + + This field is a member of `oneof`_ ``value``. + string_value (str): + A string. + + This field is a member of `oneof`_ ``value``. + """ + + boolean_value = proto.Field(proto.BOOL, number=1, oneof="value",) + int64_value = proto.Field(proto.INT64, number=2, oneof="value",) + float_value = proto.Field(proto.FLOAT, number=3, oneof="value",) + double_value = proto.Field(proto.DOUBLE, number=4, oneof="value",) + string_value = proto.Field(proto.STRING, number=5, oneof="value",) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/__init__.py b/google/ads/googleads/v12/enums/__init__.py new file mode 100644 index 000000000..d04ea7d88 --- /dev/null +++ b/google/ads/googleads/v12/enums/__init__.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +__all__ = ( + "AccessInvitationStatusEnum", + "AccessReasonEnum", + "AccessRoleEnum", + "AccountBudgetProposalStatusEnum", + "AccountBudgetProposalTypeEnum", + "AccountBudgetStatusEnum", + "AccountLinkStatusEnum", + "AdCustomizerPlaceholderFieldEnum", + "AdDestinationTypeEnum", + "AdGroupAdRotationModeEnum", + "AdGroupAdStatusEnum", + "AdGroupCriterionApprovalStatusEnum", + "AdGroupCriterionStatusEnum", + "AdGroupStatusEnum", + "AdGroupTypeEnum", + "AdNetworkTypeEnum", + "AdServingOptimizationStatusEnum", + "AdStrengthEnum", + "AdTypeEnum", + "AdvertisingChannelSubTypeEnum", + "AdvertisingChannelTypeEnum", + "AffiliateLocationFeedRelationshipTypeEnum", + "AffiliateLocationPlaceholderFieldEnum", + "AgeRangeTypeEnum", + "AppCampaignAppStoreEnum", + "AppCampaignBiddingStrategyGoalTypeEnum", + "AppPaymentModelTypeEnum", + "AppPlaceholderFieldEnum", + "AppStoreEnum", + "AppUrlOperatingSystemTypeEnum", + "AssetFieldTypeEnum", + "AssetGroupStatusEnum", + "AssetLinkStatusEnum", + "AssetPerformanceLabelEnum", + "AssetSetAssetStatusEnum", + "AssetSetLinkStatusEnum", + "AssetSetStatusEnum", + "AssetSetTypeEnum", + "AssetSourceEnum", + "AssetTypeEnum", + "AsyncActionStatusEnum", + "AttributionModelEnum", + "AudienceInsightsDimensionEnum", + "AudienceStatusEnum", + "BatchJobStatusEnum", + "BidModifierSourceEnum", + "BiddingSourceEnum", + "BiddingStrategyStatusEnum", + "BiddingStrategySystemStatusEnum", + "BiddingStrategyTypeEnum", + "BillingSetupStatusEnum", + "BrandSafetySuitabilityEnum", + "BudgetCampaignAssociationStatusEnum", + "BudgetDeliveryMethodEnum", + "BudgetPeriodEnum", + "BudgetStatusEnum", + "BudgetTypeEnum", + "CallConversionReportingStateEnum", + "CallPlaceholderFieldEnum", + "CallToActionTypeEnum", + "CallTrackingDisplayLocationEnum", + "CallTypeEnum", + "CalloutPlaceholderFieldEnum", + "CampaignCriterionStatusEnum", + "CampaignDraftStatusEnum", + "CampaignExperimentTypeEnum", + "CampaignGroupStatusEnum", + "CampaignPrimaryStatusEnum", + "CampaignPrimaryStatusReasonEnum", + "CampaignServingStatusEnum", + "CampaignSharedSetStatusEnum", + "CampaignStatusEnum", + "ChainRelationshipTypeEnum", + "ChangeClientTypeEnum", + "ChangeEventResourceTypeEnum", + "ChangeStatusOperationEnum", + "ChangeStatusResourceTypeEnum", + "ClickTypeEnum", + "CombinedAudienceStatusEnum", + "ContentLabelTypeEnum", + "ConversionActionCategoryEnum", + "ConversionActionCountingTypeEnum", + "ConversionActionStatusEnum", + "ConversionActionTypeEnum", + "ConversionAdjustmentTypeEnum", + "ConversionAttributionEventTypeEnum", + "ConversionCustomVariableStatusEnum", + "ConversionEnvironmentEnum", + "ConversionLagBucketEnum", + "ConversionOrAdjustmentLagBucketEnum", + "ConversionOriginEnum", + "ConversionTrackingStatusEnum", + "ConversionValueRulePrimaryDimensionEnum", + "ConversionValueRuleSetStatusEnum", + "ConversionValueRuleStatusEnum", + "CriterionCategoryChannelAvailabilityModeEnum", + "CriterionCategoryLocaleAvailabilityModeEnum", + "CriterionSystemServingStatusEnum", + "CriterionTypeEnum", + "CustomAudienceMemberTypeEnum", + "CustomAudienceStatusEnum", + "CustomAudienceTypeEnum", + "CustomConversionGoalStatusEnum", + "CustomInterestMemberTypeEnum", + "CustomInterestStatusEnum", + "CustomInterestTypeEnum", + "CustomPlaceholderFieldEnum", + "CustomerMatchUploadKeyTypeEnum", + "CustomerPayPerConversionEligibilityFailureReasonEnum", + "CustomerStatusEnum", + "CustomizerAttributeStatusEnum", + "CustomizerAttributeTypeEnum", + "CustomizerValueStatusEnum", + "DataDrivenModelStatusEnum", + "DayOfWeekEnum", + "DeviceEnum", + "DisplayAdFormatSettingEnum", + "DisplayUploadProductTypeEnum", + "DistanceBucketEnum", + "DsaPageFeedCriterionFieldEnum", + "EducationPlaceholderFieldEnum", + "ExperimentMetricDirectionEnum", + "ExperimentMetricEnum", + "ExperimentStatusEnum", + "ExperimentTypeEnum", + "ExtensionSettingDeviceEnum", + "ExtensionTypeEnum", + "ExternalConversionSourceEnum", + "FeedAttributeTypeEnum", + "FeedItemQualityApprovalStatusEnum", + "FeedItemQualityDisapprovalReasonEnum", + "FeedItemSetStatusEnum", + "FeedItemSetStringFilterTypeEnum", + "FeedItemStatusEnum", + "FeedItemTargetDeviceEnum", + "FeedItemTargetStatusEnum", + "FeedItemTargetTypeEnum", + "FeedItemValidationStatusEnum", + "FeedLinkStatusEnum", + "FeedMappingCriterionTypeEnum", + "FeedMappingStatusEnum", + "FeedOriginEnum", + "FeedStatusEnum", + "FlightPlaceholderFieldEnum", + "FrequencyCapEventTypeEnum", + "FrequencyCapLevelEnum", + "FrequencyCapTimeUnitEnum", + "GenderTypeEnum", + "GeoTargetConstantStatusEnum", + "GeoTargetingRestrictionEnum", + "GeoTargetingTypeEnum", + "GoalConfigLevelEnum", + "GoogleAdsFieldCategoryEnum", + "GoogleAdsFieldDataTypeEnum", + "GoogleVoiceCallStatusEnum", + "HotelDateSelectionTypeEnum", + "HotelPlaceholderFieldEnum", + "HotelPriceBucketEnum", + "HotelRateTypeEnum", + "HotelReconciliationStatusEnum", + "ImagePlaceholderFieldEnum", + "IncomeRangeTypeEnum", + "InteractionEventTypeEnum", + "InteractionTypeEnum", + "InvoiceTypeEnum", + "JobPlaceholderFieldEnum", + "KeywordMatchTypeEnum", + "KeywordPlanAggregateMetricTypeEnum", + "KeywordPlanCompetitionLevelEnum", + "KeywordPlanConceptGroupTypeEnum", + "KeywordPlanForecastIntervalEnum", + "KeywordPlanKeywordAnnotationEnum", + "KeywordPlanNetworkEnum", + "LabelStatusEnum", + "LeadFormCallToActionTypeEnum", + "LeadFormDesiredIntentEnum", + "LeadFormFieldUserInputTypeEnum", + "LeadFormPostSubmitCallToActionTypeEnum", + "LegacyAppInstallAdAppStoreEnum", + "LinkedAccountTypeEnum", + "ListingGroupFilterBiddingCategoryLevelEnum", + "ListingGroupFilterCustomAttributeIndexEnum", + "ListingGroupFilterProductChannelEnum", + "ListingGroupFilterProductConditionEnum", + "ListingGroupFilterProductTypeLevelEnum", + "ListingGroupFilterTypeEnum", + "ListingGroupFilterVerticalEnum", + "ListingGroupTypeEnum", + "LocalPlaceholderFieldEnum", + "LocationExtensionTargetingCriterionFieldEnum", + "LocationGroupRadiusUnitsEnum", + "LocationOwnershipTypeEnum", + "LocationPlaceholderFieldEnum", + "LocationSourceTypeEnum", + "LocationStringFilterTypeEnum", + "ManagerLinkStatusEnum", + "MatchingFunctionContextTypeEnum", + "MatchingFunctionOperatorEnum", + "MediaTypeEnum", + "MerchantCenterLinkStatusEnum", + "MessagePlaceholderFieldEnum", + "MimeTypeEnum", + "MinuteOfHourEnum", + "MobileAppVendorEnum", + "MobileDeviceTypeEnum", + "MonthOfYearEnum", + "NegativeGeoTargetTypeEnum", + "OfflineUserDataJobFailureReasonEnum", + "OfflineUserDataJobMatchRateRangeEnum", + "OfflineUserDataJobStatusEnum", + "OfflineUserDataJobTypeEnum", + "OperatingSystemVersionOperatorTypeEnum", + "OptimizationGoalTypeEnum", + "ParentalStatusTypeEnum", + "PaymentModeEnum", + "PerformanceMaxUpgradeStatusEnum", + "PlaceholderTypeEnum", + "PlacementTypeEnum", + "PolicyApprovalStatusEnum", + "PolicyReviewStatusEnum", + "PolicyTopicEntryTypeEnum", + "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", + "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", + "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", + "PositiveGeoTargetTypeEnum", + "PreferredContentTypeEnum", + "PriceExtensionPriceQualifierEnum", + "PriceExtensionPriceUnitEnum", + "PriceExtensionTypeEnum", + "PricePlaceholderFieldEnum", + "ProductBiddingCategoryLevelEnum", + "ProductBiddingCategoryStatusEnum", + "ProductChannelEnum", + "ProductChannelExclusivityEnum", + "ProductConditionEnum", + "ProductCustomAttributeIndexEnum", + "ProductTypeLevelEnum", + "PromotionExtensionDiscountModifierEnum", + "PromotionExtensionOccasionEnum", + "PromotionPlaceholderFieldEnum", + "ProximityRadiusUnitsEnum", + "QualityScoreBucketEnum", + "ReachPlanAgeRangeEnum", + "ReachPlanNetworkEnum", + "RealEstatePlaceholderFieldEnum", + "RecommendationTypeEnum", + "ResourceChangeOperationEnum", + "ResourceLimitTypeEnum", + "ResponseContentTypeEnum", + "SearchEngineResultsPageTypeEnum", + "SearchTermMatchTypeEnum", + "SearchTermTargetingStatusEnum", + "SeasonalityEventScopeEnum", + "SeasonalityEventStatusEnum", + "ServedAssetFieldTypeEnum", + "SharedSetStatusEnum", + "SharedSetTypeEnum", + "SimulationModificationMethodEnum", + "SimulationTypeEnum", + "SitelinkPlaceholderFieldEnum", + "SkAdNetworkAdEventTypeEnum", + "SkAdNetworkAttributionCreditEnum", + "SkAdNetworkUserTypeEnum", + "SlotEnum", + "SpendingLimitTypeEnum", + "StructuredSnippetPlaceholderFieldEnum", + "SummaryRowSettingEnum", + "SystemManagedResourceSourceEnum", + "TargetCpaOptInRecommendationGoalEnum", + "TargetImpressionShareLocationEnum", + "TargetingDimensionEnum", + "TimeTypeEnum", + "TrackingCodePageFormatEnum", + "TrackingCodeTypeEnum", + "TravelPlaceholderFieldEnum", + "UserIdentifierSourceEnum", + "UserInterestTaxonomyTypeEnum", + "UserListAccessStatusEnum", + "UserListClosingReasonEnum", + "UserListCombinedRuleOperatorEnum", + "UserListCrmDataSourceTypeEnum", + "UserListDateRuleItemOperatorEnum", + "UserListFlexibleRuleOperatorEnum", + "UserListLogicalRuleOperatorEnum", + "UserListMembershipStatusEnum", + "UserListNumberRuleItemOperatorEnum", + "UserListPrepopulationStatusEnum", + "UserListRuleTypeEnum", + "UserListSizeRangeEnum", + "UserListStringRuleItemOperatorEnum", + "UserListTypeEnum", + "ValueRuleDeviceTypeEnum", + "ValueRuleGeoLocationMatchTypeEnum", + "ValueRuleOperationEnum", + "ValueRuleSetAttachmentTypeEnum", + "ValueRuleSetDimensionEnum", + "VanityPharmaDisplayUrlModeEnum", + "VanityPharmaTextEnum", + "VideoThumbnailEnum", + "WebpageConditionOperandEnum", + "WebpageConditionOperatorEnum", +) diff --git a/google/ads/googleads/v12/enums/services/__init__.py b/google/ads/googleads/v12/enums/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/enums/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/enums/types/__init__.py b/google/ads/googleads/v12/enums/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/enums/types/access_invitation_status.py b/google/ads/googleads/v12/enums/types/access_invitation_status.py new file mode 100644 index 000000000..17155c65f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/access_invitation_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccessInvitationStatusEnum",}, +) + + +class AccessInvitationStatusEnum(proto.Message): + r"""Container for enum for identifying the status of access + invitation + + """ + + class AccessInvitationStatus(proto.Enum): + r"""Possible access invitation status of a user""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + DECLINED = 3 + EXPIRED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/access_reason.py b/google/ads/googleads/v12/enums/types/access_reason.py new file mode 100644 index 000000000..dfedc481b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/access_reason.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccessReasonEnum",}, +) + + +class AccessReasonEnum(proto.Message): + r"""Indicates the way the resource such as user list is related + to a user. + + """ + + class AccessReason(proto.Enum): + r"""Enum describing possible access reasons.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OWNED = 2 + SHARED = 3 + LICENSED = 4 + SUBSCRIBED = 5 + AFFILIATED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/access_role.py b/google/ads/googleads/v12/enums/types/access_role.py new file mode 100644 index 000000000..581c77e1d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/access_role.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccessRoleEnum",}, +) + + +class AccessRoleEnum(proto.Message): + r"""Container for enum describing possible access role for user. + """ + + class AccessRole(proto.Enum): + r"""Possible access role of a user.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADMIN = 2 + STANDARD = 3 + READ_ONLY = 4 + EMAIL_ONLY = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/account_budget_proposal_status.py b/google/ads/googleads/v12/enums/types/account_budget_proposal_status.py new file mode 100644 index 000000000..39486c013 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/account_budget_proposal_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccountBudgetProposalStatusEnum",}, +) + + +class AccountBudgetProposalStatusEnum(proto.Message): + r"""Message describing AccountBudgetProposal statuses. + """ + + class AccountBudgetProposalStatus(proto.Enum): + r"""The possible statuses of an AccountBudgetProposal.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + APPROVED_HELD = 3 + APPROVED = 4 + CANCELLED = 5 + REJECTED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/account_budget_proposal_type.py b/google/ads/googleads/v12/enums/types/account_budget_proposal_type.py new file mode 100644 index 000000000..3e7518b98 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/account_budget_proposal_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccountBudgetProposalTypeEnum",}, +) + + +class AccountBudgetProposalTypeEnum(proto.Message): + r"""Message describing AccountBudgetProposal types. + """ + + class AccountBudgetProposalType(proto.Enum): + r"""The possible types of an AccountBudgetProposal.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CREATE = 2 + UPDATE = 3 + END = 4 + REMOVE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/account_budget_status.py b/google/ads/googleads/v12/enums/types/account_budget_status.py new file mode 100644 index 000000000..072e0649a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/account_budget_status.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccountBudgetStatusEnum",}, +) + + +class AccountBudgetStatusEnum(proto.Message): + r"""Message describing AccountBudget statuses. + """ + + class AccountBudgetStatus(proto.Enum): + r"""The possible statuses of an AccountBudget.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + APPROVED = 3 + CANCELLED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/account_link_status.py b/google/ads/googleads/v12/enums/types/account_link_status.py new file mode 100644 index 000000000..85aa4f7c4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/account_link_status.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AccountLinkStatusEnum",}, +) + + +class AccountLinkStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an account + link. + + """ + + class AccountLinkStatus(proto.Enum): + r"""Describes the possible statuses for a link between a Google + Ads customer and another account. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + REQUESTED = 4 + PENDING_APPROVAL = 5 + REJECTED = 6 + REVOKED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_customizer_placeholder_field.py b/google/ads/googleads/v12/enums/types/ad_customizer_placeholder_field.py new file mode 100644 index 000000000..42a65b176 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_customizer_placeholder_field.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdCustomizerPlaceholderFieldEnum",}, +) + + +class AdCustomizerPlaceholderFieldEnum(proto.Message): + r"""Values for Ad Customizer placeholder fields. + """ + + class AdCustomizerPlaceholderField(proto.Enum): + r"""Possible values for Ad Customizers placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INTEGER = 2 + PRICE = 3 + DATE = 4 + STRING = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_destination_type.py b/google/ads/googleads/v12/enums/types/ad_destination_type.py new file mode 100644 index 000000000..46d88185d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_destination_type.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdDestinationTypeEnum",}, +) + + +class AdDestinationTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads destination types. + """ + + class AdDestinationType(proto.Enum): + r"""Enumerates Google Ads destination types""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_APPLICABLE = 2 + WEBSITE = 3 + APP_DEEP_LINK = 4 + APP_STORE = 5 + PHONE_CALL = 6 + MAP_DIRECTIONS = 7 + LOCATION_LISTING = 8 + MESSAGE = 9 + LEAD_FORM = 10 + YOUTUBE = 11 + UNMODELED_FOR_CONVERSIONS = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_ad_rotation_mode.py b/google/ads/googleads/v12/enums/types/ad_group_ad_rotation_mode.py new file mode 100644 index 000000000..3461fcd9d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_ad_rotation_mode.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdRotationModeEnum",}, +) + + +class AdGroupAdRotationModeEnum(proto.Message): + r"""Container for enum describing possible ad rotation modes of + ads within an ad group. + + """ + + class AdGroupAdRotationMode(proto.Enum): + r"""The possible ad rotation modes of an ad group.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPTIMIZE = 2 + ROTATE_FOREVER = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_ad_status.py b/google/ads/googleads/v12/enums/types/ad_group_ad_status.py new file mode 100644 index 000000000..666cd9105 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_ad_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdStatusEnum",}, +) + + +class AdGroupAdStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an + AdGroupAd. + + """ + + class AdGroupAdStatus(proto.Enum): + r"""The possible statuses of an AdGroupAd.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_criterion_approval_status.py b/google/ads/googleads/v12/enums/types/ad_group_criterion_approval_status.py new file mode 100644 index 000000000..5bf966b52 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_criterion_approval_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionApprovalStatusEnum",}, +) + + +class AdGroupCriterionApprovalStatusEnum(proto.Message): + r"""Container for enum describing possible AdGroupCriterion + approval statuses. + + """ + + class AdGroupCriterionApprovalStatus(proto.Enum): + r"""Enumerates AdGroupCriterion approval statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APPROVED = 2 + DISAPPROVED = 3 + PENDING_REVIEW = 4 + UNDER_REVIEW = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_criterion_status.py b/google/ads/googleads/v12/enums/types/ad_group_criterion_status.py new file mode 100644 index 000000000..47b8597de --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_criterion_status.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionStatusEnum",}, +) + + +class AdGroupCriterionStatusEnum(proto.Message): + r"""Message describing AdGroupCriterion statuses. + """ + + class AdGroupCriterionStatus(proto.Enum): + r"""The possible statuses of an AdGroupCriterion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_status.py b/google/ads/googleads/v12/enums/types/ad_group_status.py new file mode 100644 index 000000000..4890723ea --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupStatusEnum",}, +) + + +class AdGroupStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an ad + group. + + """ + + class AdGroupStatus(proto.Enum): + r"""The possible statuses of an ad group.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_group_type.py b/google/ads/googleads/v12/enums/types/ad_group_type.py new file mode 100644 index 000000000..fae358b3c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_group_type.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdGroupTypeEnum",}, +) + + +class AdGroupTypeEnum(proto.Message): + r"""Defines types of an ad group, specific to a particular + campaign channel type. This type drives validations that + restrict which entities can be added to the ad group. + + """ + + class AdGroupType(proto.Enum): + r"""Enum listing the possible types of an ad group.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH_STANDARD = 2 + DISPLAY_STANDARD = 3 + SHOPPING_PRODUCT_ADS = 4 + HOTEL_ADS = 6 + SHOPPING_SMART_ADS = 7 + VIDEO_BUMPER = 8 + VIDEO_TRUE_VIEW_IN_STREAM = 9 + VIDEO_TRUE_VIEW_IN_DISPLAY = 10 + VIDEO_NON_SKIPPABLE_IN_STREAM = 11 + VIDEO_OUTSTREAM = 12 + SEARCH_DYNAMIC_ADS = 13 + SHOPPING_COMPARISON_LISTING_ADS = 14 + PROMOTED_HOTEL_ADS = 15 + VIDEO_RESPONSIVE = 16 + VIDEO_EFFICIENT_REACH = 17 + SMART_CAMPAIGN_ADS = 18 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_network_type.py b/google/ads/googleads/v12/enums/types/ad_network_type.py new file mode 100644 index 000000000..6721a6866 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_network_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdNetworkTypeEnum",}, +) + + +class AdNetworkTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads network types. + """ + + class AdNetworkType(proto.Enum): + r"""Enumerates Google Ads network types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH = 2 + SEARCH_PARTNERS = 3 + CONTENT = 4 + YOUTUBE_SEARCH = 5 + YOUTUBE_WATCH = 6 + MIXED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_serving_optimization_status.py b/google/ads/googleads/v12/enums/types/ad_serving_optimization_status.py new file mode 100644 index 000000000..3493ab2b5 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_serving_optimization_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdServingOptimizationStatusEnum",}, +) + + +class AdServingOptimizationStatusEnum(proto.Message): + r"""Possible ad serving statuses of a campaign. + """ + + class AdServingOptimizationStatus(proto.Enum): + r"""Enum describing possible serving statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPTIMIZE = 2 + CONVERSION_OPTIMIZE = 3 + ROTATE = 4 + ROTATE_INDEFINITELY = 5 + UNAVAILABLE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_strength.py b/google/ads/googleads/v12/enums/types/ad_strength.py new file mode 100644 index 000000000..51b1c07d0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_strength.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdStrengthEnum",}, +) + + +class AdStrengthEnum(proto.Message): + r"""Container for enum describing possible ad strengths. + """ + + class AdStrength(proto.Enum): + r"""Enum listing the possible ad strengths.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + NO_ADS = 3 + POOR = 4 + AVERAGE = 5 + GOOD = 6 + EXCELLENT = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/ad_type.py b/google/ads/googleads/v12/enums/types/ad_type.py new file mode 100644 index 000000000..0fb8cc12a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/ad_type.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdTypeEnum",}, +) + + +class AdTypeEnum(proto.Message): + r"""Container for enum describing possible types of an ad. + """ + + class AdType(proto.Enum): + r"""The possible types of an ad.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TEXT_AD = 2 + EXPANDED_TEXT_AD = 3 + EXPANDED_DYNAMIC_SEARCH_AD = 7 + HOTEL_AD = 8 + SHOPPING_SMART_AD = 9 + SHOPPING_PRODUCT_AD = 10 + VIDEO_AD = 12 + IMAGE_AD = 14 + RESPONSIVE_SEARCH_AD = 15 + LEGACY_RESPONSIVE_DISPLAY_AD = 16 + APP_AD = 17 + LEGACY_APP_INSTALL_AD = 18 + RESPONSIVE_DISPLAY_AD = 19 + LOCAL_AD = 20 + HTML5_UPLOAD_AD = 21 + DYNAMIC_HTML5_AD = 22 + APP_ENGAGEMENT_AD = 23 + SHOPPING_COMPARISON_LISTING_AD = 24 + VIDEO_BUMPER_AD = 25 + VIDEO_NON_SKIPPABLE_IN_STREAM_AD = 26 + VIDEO_OUTSTREAM_AD = 27 + VIDEO_TRUEVIEW_IN_STREAM_AD = 29 + VIDEO_RESPONSIVE_AD = 30 + SMART_CAMPAIGN_AD = 31 + CALL_AD = 32 + APP_PRE_REGISTRATION_AD = 33 + IN_FEED_VIDEO_AD = 34 + DISCOVERY_MULTI_ASSET_AD = 35 + DISCOVERY_CAROUSEL_AD = 36 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/advertising_channel_sub_type.py b/google/ads/googleads/v12/enums/types/advertising_channel_sub_type.py new file mode 100644 index 000000000..c4ca6d459 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/advertising_channel_sub_type.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdvertisingChannelSubTypeEnum",}, +) + + +class AdvertisingChannelSubTypeEnum(proto.Message): + r"""An immutable specialization of an Advertising Channel. + """ + + class AdvertisingChannelSubType(proto.Enum): + r"""Enum describing the different channel subtypes.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH_MOBILE_APP = 2 + DISPLAY_MOBILE_APP = 3 + SEARCH_EXPRESS = 4 + DISPLAY_EXPRESS = 5 + SHOPPING_SMART_ADS = 6 + DISPLAY_GMAIL_AD = 7 + DISPLAY_SMART_CAMPAIGN = 8 + VIDEO_OUTSTREAM = 9 + VIDEO_ACTION = 10 + VIDEO_NON_SKIPPABLE = 11 + APP_CAMPAIGN = 12 + APP_CAMPAIGN_FOR_ENGAGEMENT = 13 + LOCAL_CAMPAIGN = 14 + SHOPPING_COMPARISON_LISTING_ADS = 15 + SMART_CAMPAIGN = 16 + VIDEO_SEQUENCE = 17 + APP_CAMPAIGN_FOR_PRE_REGISTRATION = 18 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/advertising_channel_type.py b/google/ads/googleads/v12/enums/types/advertising_channel_type.py new file mode 100644 index 000000000..b8e8e2415 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/advertising_channel_type.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AdvertisingChannelTypeEnum",}, +) + + +class AdvertisingChannelTypeEnum(proto.Message): + r"""The channel type a campaign may target to serve on. + """ + + class AdvertisingChannelType(proto.Enum): + r"""Enum describing the various advertising channel types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH = 2 + DISPLAY = 3 + SHOPPING = 4 + HOTEL = 5 + VIDEO = 6 + MULTI_CHANNEL = 7 + LOCAL = 8 + SMART = 9 + PERFORMANCE_MAX = 10 + LOCAL_SERVICES = 11 + DISCOVERY = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/affiliate_location_feed_relationship_type.py b/google/ads/googleads/v12/enums/types/affiliate_location_feed_relationship_type.py new file mode 100644 index 000000000..8338a9b5e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/affiliate_location_feed_relationship_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AffiliateLocationFeedRelationshipTypeEnum",}, +) + + +class AffiliateLocationFeedRelationshipTypeEnum(proto.Message): + r"""Container for enum describing possible values for a + relationship type for an affiliate location feed. + + """ + + class AffiliateLocationFeedRelationshipType(proto.Enum): + r"""Possible values for a relationship type for an affiliate + location feed. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + GENERAL_RETAILER = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/affiliate_location_placeholder_field.py b/google/ads/googleads/v12/enums/types/affiliate_location_placeholder_field.py new file mode 100644 index 000000000..60bbc505c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/affiliate_location_placeholder_field.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AffiliateLocationPlaceholderFieldEnum",}, +) + + +class AffiliateLocationPlaceholderFieldEnum(proto.Message): + r"""Values for Affiliate Location placeholder fields. + """ + + class AffiliateLocationPlaceholderField(proto.Enum): + r"""Possible values for Affiliate Location placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BUSINESS_NAME = 2 + ADDRESS_LINE_1 = 3 + ADDRESS_LINE_2 = 4 + CITY = 5 + PROVINCE = 6 + POSTAL_CODE = 7 + COUNTRY_CODE = 8 + PHONE_NUMBER = 9 + LANGUAGE_CODE = 10 + CHAIN_ID = 11 + CHAIN_NAME = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/age_range_type.py b/google/ads/googleads/v12/enums/types/age_range_type.py new file mode 100644 index 000000000..70dc14b39 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/age_range_type.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AgeRangeTypeEnum",}, +) + + +class AgeRangeTypeEnum(proto.Message): + r"""Container for enum describing the type of demographic age + ranges. + + """ + + class AgeRangeType(proto.Enum): + r"""The type of demographic age ranges (for example, between 18 + and 24 years old). + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + AGE_RANGE_18_24 = 503001 + AGE_RANGE_25_34 = 503002 + AGE_RANGE_35_44 = 503003 + AGE_RANGE_45_54 = 503004 + AGE_RANGE_55_64 = 503005 + AGE_RANGE_65_UP = 503006 + AGE_RANGE_UNDETERMINED = 503999 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_campaign_app_store.py b/google/ads/googleads/v12/enums/types/app_campaign_app_store.py new file mode 100644 index 000000000..564556b1c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_campaign_app_store.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppCampaignAppStoreEnum",}, +) + + +class AppCampaignAppStoreEnum(proto.Message): + r"""The application store that distributes mobile applications. + """ + + class AppCampaignAppStore(proto.Enum): + r"""Enum describing app campaign app store.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APPLE_APP_STORE = 2 + GOOGLE_APP_STORE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_campaign_bidding_strategy_goal_type.py b/google/ads/googleads/v12/enums/types/app_campaign_bidding_strategy_goal_type.py new file mode 100644 index 000000000..5a2643a21 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_campaign_bidding_strategy_goal_type.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppCampaignBiddingStrategyGoalTypeEnum",}, +) + + +class AppCampaignBiddingStrategyGoalTypeEnum(proto.Message): + r"""Container for enum describing goal towards which the bidding + strategy of an app campaign should optimize for. + + """ + + class AppCampaignBiddingStrategyGoalType(proto.Enum): + r"""Goal type of App campaign BiddingStrategy.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPTIMIZE_INSTALLS_TARGET_INSTALL_COST = 2 + OPTIMIZE_IN_APP_CONVERSIONS_TARGET_INSTALL_COST = 3 + OPTIMIZE_IN_APP_CONVERSIONS_TARGET_CONVERSION_COST = 4 + OPTIMIZE_RETURN_ON_ADVERTISING_SPEND = 5 + OPTIMIZE_PRE_REGISTRATION_CONVERSION_VOLUME = 6 + OPTIMIZE_INSTALLS_WITHOUT_TARGET_INSTALL_COST = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_payment_model_type.py b/google/ads/googleads/v12/enums/types/app_payment_model_type.py new file mode 100644 index 000000000..c65cc11a8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_payment_model_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppPaymentModelTypeEnum",}, +) + + +class AppPaymentModelTypeEnum(proto.Message): + r"""Represents a criterion for targeting paid apps. + """ + + class AppPaymentModelType(proto.Enum): + r"""Enum describing possible app payment models.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PAID = 30 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_placeholder_field.py b/google/ads/googleads/v12/enums/types/app_placeholder_field.py new file mode 100644 index 000000000..2616c2423 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_placeholder_field.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppPlaceholderFieldEnum",}, +) + + +class AppPlaceholderFieldEnum(proto.Message): + r"""Values for App placeholder fields. + """ + + class AppPlaceholderField(proto.Enum): + r"""Possible values for App placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + STORE = 2 + ID = 3 + LINK_TEXT = 4 + URL = 5 + FINAL_URLS = 6 + FINAL_MOBILE_URLS = 7 + TRACKING_URL = 8 + FINAL_URL_SUFFIX = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_store.py b/google/ads/googleads/v12/enums/types/app_store.py new file mode 100644 index 000000000..83cc669b0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_store.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppStoreEnum",}, +) + + +class AppStoreEnum(proto.Message): + r"""Container for enum describing app store type in an app + extension. + + """ + + class AppStore(proto.Enum): + r"""App store type in an app extension.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APPLE_ITUNES = 2 + GOOGLE_PLAY = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/app_url_operating_system_type.py b/google/ads/googleads/v12/enums/types/app_url_operating_system_type.py new file mode 100644 index 000000000..f037f75f7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/app_url_operating_system_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AppUrlOperatingSystemTypeEnum",}, +) + + +class AppUrlOperatingSystemTypeEnum(proto.Message): + r"""The possible OS types for a deeplink AppUrl. + """ + + class AppUrlOperatingSystemType(proto.Enum): + r"""Operating System""" + UNSPECIFIED = 0 + UNKNOWN = 1 + IOS = 2 + ANDROID = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_field_type.py b/google/ads/googleads/v12/enums/types/asset_field_type.py new file mode 100644 index 000000000..c17e80812 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_field_type.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetFieldTypeEnum",}, +) + + +class AssetFieldTypeEnum(proto.Message): + r"""Container for enum describing the possible placements of an + asset. + + """ + + class AssetFieldType(proto.Enum): + r"""Enum describing the possible placements of an asset.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + HEADLINE = 2 + DESCRIPTION = 3 + MANDATORY_AD_TEXT = 4 + MARKETING_IMAGE = 5 + MEDIA_BUNDLE = 6 + YOUTUBE_VIDEO = 7 + BOOK_ON_GOOGLE = 8 + LEAD_FORM = 9 + PROMOTION = 10 + CALLOUT = 11 + STRUCTURED_SNIPPET = 12 + SITELINK = 13 + MOBILE_APP = 14 + HOTEL_CALLOUT = 15 + CALL = 16 + PRICE = 24 + LONG_HEADLINE = 17 + BUSINESS_NAME = 18 + SQUARE_MARKETING_IMAGE = 19 + PORTRAIT_MARKETING_IMAGE = 20 + LOGO = 21 + LANDSCAPE_LOGO = 22 + VIDEO = 23 + CALL_TO_ACTION_SELECTION = 25 + AD_IMAGE = 26 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_group_status.py b/google/ads/googleads/v12/enums/types/asset_group_status.py new file mode 100644 index 000000000..f94a93608 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_group_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupStatusEnum",}, +) + + +class AssetGroupStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an asset + group. + + """ + + class AssetGroupStatus(proto.Enum): + r"""The possible statuses of an asset group.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_link_status.py b/google/ads/googleads/v12/enums/types/asset_link_status.py new file mode 100644 index 000000000..2d6591fde --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_link_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetLinkStatusEnum",}, +) + + +class AssetLinkStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an asset + link. + + """ + + class AssetLinkStatus(proto.Enum): + r"""Enum describing statuses of an asset link.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + PAUSED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_performance_label.py b/google/ads/googleads/v12/enums/types/asset_performance_label.py new file mode 100644 index 000000000..d7651e364 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_performance_label.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetPerformanceLabelEnum",}, +) + + +class AssetPerformanceLabelEnum(proto.Message): + r"""Container for enum describing the performance label of an + asset. + + """ + + class AssetPerformanceLabel(proto.Enum): + r"""Enum describing the possible performance labels of an asset, + usually computed in the context of a linkage. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + LEARNING = 3 + LOW = 4 + GOOD = 5 + BEST = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_set_asset_status.py b/google/ads/googleads/v12/enums/types/asset_set_asset_status.py new file mode 100644 index 000000000..2bc965c17 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_set_asset_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetSetAssetStatusEnum",}, +) + + +class AssetSetAssetStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an asset + set asset. + + """ + + class AssetSetAssetStatus(proto.Enum): + r"""The possible statuses of an asset set asset.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_set_link_status.py b/google/ads/googleads/v12/enums/types/asset_set_link_status.py new file mode 100644 index 000000000..7e193ede6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_set_link_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetSetLinkStatusEnum",}, +) + + +class AssetSetLinkStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of the + linkage between asset set and its container. + + """ + + class AssetSetLinkStatus(proto.Enum): + r"""The possible statuses of the linkage between asset set and + its container. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_set_status.py b/google/ads/googleads/v12/enums/types/asset_set_status.py new file mode 100644 index 000000000..befd3e154 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_set_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetSetStatusEnum",}, +) + + +class AssetSetStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of an asset + set. + + """ + + class AssetSetStatus(proto.Enum): + r"""The possible statuses of an asset set.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_set_type.py b/google/ads/googleads/v12/enums/types/asset_set_type.py new file mode 100644 index 000000000..dd0ef48b1 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_set_type.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetSetTypeEnum",}, +) + + +class AssetSetTypeEnum(proto.Message): + r"""Container for enum describing possible types of an asset set. + """ + + class AssetSetType(proto.Enum): + r"""Possible types of an asset set.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PAGE_FEED = 2 + DYNAMIC_EDUCATION = 3 + MERCHANT_CENTER_FEED = 4 + DYNAMIC_REAL_ESTATE = 5 + DYNAMIC_CUSTOM = 6 + DYNAMIC_HOTELS_AND_RENTALS = 7 + DYNAMIC_FLIGHTS = 8 + DYNAMIC_TRAVEL = 9 + DYNAMIC_LOCAL = 10 + DYNAMIC_JOBS = 11 + LOCATION_SYNC = 12 + BUSINESS_PROFILE_DYNAMIC_LOCATION_GROUP = 13 + CHAIN_DYNAMIC_LOCATION_GROUP = 14 + STATIC_LOCATION_GROUP = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_source.py b/google/ads/googleads/v12/enums/types/asset_source.py new file mode 100644 index 000000000..a0443915e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_source.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetSourceEnum",}, +) + + +class AssetSourceEnum(proto.Message): + r"""Source of the asset or asset link for who generated the + entity. For example, advertiser or automatically created. + + """ + + class AssetSource(proto.Enum): + r"""Enum describing possible source of asset.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADVERTISER = 2 + AUTOMATICALLY_CREATED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/asset_type.py b/google/ads/googleads/v12/enums/types/asset_type.py new file mode 100644 index 000000000..1bf3d1747 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/asset_type.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AssetTypeEnum",}, +) + + +class AssetTypeEnum(proto.Message): + r"""Container for enum describing the types of asset. + """ + + class AssetType(proto.Enum): + r"""Enum describing possible types of asset.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + YOUTUBE_VIDEO = 2 + MEDIA_BUNDLE = 3 + IMAGE = 4 + TEXT = 5 + LEAD_FORM = 6 + BOOK_ON_GOOGLE = 7 + PROMOTION = 8 + CALLOUT = 9 + STRUCTURED_SNIPPET = 10 + SITELINK = 11 + PAGE_FEED = 12 + DYNAMIC_EDUCATION = 13 + MOBILE_APP = 14 + HOTEL_CALLOUT = 15 + CALL = 16 + PRICE = 17 + CALL_TO_ACTION = 18 + DYNAMIC_REAL_ESTATE = 19 + DYNAMIC_CUSTOM = 20 + DYNAMIC_HOTELS_AND_RENTALS = 21 + DYNAMIC_FLIGHTS = 22 + DISCOVERY_CAROUSEL_CARD = 23 + DYNAMIC_TRAVEL = 24 + DYNAMIC_LOCAL = 25 + DYNAMIC_JOBS = 26 + LOCATION = 27 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/async_action_status.py b/google/ads/googleads/v12/enums/types/async_action_status.py new file mode 100644 index 000000000..2adf247a4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/async_action_status.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AsyncActionStatusEnum",}, +) + + +class AsyncActionStatusEnum(proto.Message): + r"""Container for enum describing the experiment async action + status. + + """ + + class AsyncActionStatus(proto.Enum): + r"""The async action status of the experiment.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_STARTED = 2 + IN_PROGRESS = 3 + COMPLETED = 4 + FAILED = 5 + COMPLETED_WITH_WARNING = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/attribution_model.py b/google/ads/googleads/v12/enums/types/attribution_model.py new file mode 100644 index 000000000..636216978 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/attribution_model.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AttributionModelEnum",}, +) + + +class AttributionModelEnum(proto.Message): + r"""Container for enum representing the attribution model that + describes how to distribute credit for a particular conversion + across potentially many prior interactions. + + """ + + class AttributionModel(proto.Enum): + r"""The attribution model that describes how to distribute credit + for a particular conversion across potentially many prior + interactions. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + EXTERNAL = 100 + GOOGLE_ADS_LAST_CLICK = 101 + GOOGLE_SEARCH_ATTRIBUTION_FIRST_CLICK = 102 + GOOGLE_SEARCH_ATTRIBUTION_LINEAR = 103 + GOOGLE_SEARCH_ATTRIBUTION_TIME_DECAY = 104 + GOOGLE_SEARCH_ATTRIBUTION_POSITION_BASED = 105 + GOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN = 106 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/audience_insights_dimension.py b/google/ads/googleads/v12/enums/types/audience_insights_dimension.py new file mode 100644 index 000000000..e6ec47b35 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/audience_insights_dimension.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AudienceInsightsDimensionEnum",}, +) + + +class AudienceInsightsDimensionEnum(proto.Message): + r"""Container for enum describing audience insights dimensions. + """ + + class AudienceInsightsDimension(proto.Enum): + r"""Possible audience dimensions for use in generating insights.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CATEGORY = 2 + KNOWLEDGE_GRAPH = 3 + GEO_TARGET_COUNTRY = 4 + SUB_COUNTRY_LOCATION = 5 + YOUTUBE_CHANNEL = 6 + YOUTUBE_DYNAMIC_LINEUP = 7 + AFFINITY_USER_INTEREST = 8 + IN_MARKET_USER_INTEREST = 9 + PARENTAL_STATUS = 10 + INCOME_RANGE = 11 + AGE_RANGE = 12 + GENDER = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/audience_status.py b/google/ads/googleads/v12/enums/types/audience_status.py new file mode 100644 index 000000000..aa3567424 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/audience_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"AudienceStatusEnum",}, +) + + +class AudienceStatusEnum(proto.Message): + r"""The status of audience. + """ + + class AudienceStatus(proto.Enum): + r"""Enum containing possible audience status types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/batch_job_status.py b/google/ads/googleads/v12/enums/types/batch_job_status.py new file mode 100644 index 000000000..b18c03300 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/batch_job_status.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BatchJobStatusEnum",}, +) + + +class BatchJobStatusEnum(proto.Message): + r"""Container for enum describing possible batch job statuses. + """ + + class BatchJobStatus(proto.Enum): + r"""The batch job statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + RUNNING = 3 + DONE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/bid_modifier_source.py b/google/ads/googleads/v12/enums/types/bid_modifier_source.py new file mode 100644 index 000000000..3125882a4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/bid_modifier_source.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BidModifierSourceEnum",}, +) + + +class BidModifierSourceEnum(proto.Message): + r"""Container for enum describing possible bid modifier sources. + """ + + class BidModifierSource(proto.Enum): + r"""Enum describing possible bid modifier sources.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN = 2 + AD_GROUP = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/bidding_source.py b/google/ads/googleads/v12/enums/types/bidding_source.py new file mode 100644 index 000000000..d12750744 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/bidding_source.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BiddingSourceEnum",}, +) + + +class BiddingSourceEnum(proto.Message): + r"""Container for enum describing possible bidding sources. + """ + + class BiddingSource(proto.Enum): + r"""Indicates where a bid or target is defined. For example, an + ad group criterion may define a cpc bid directly, or it can + inherit its cpc bid from the ad group. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN_BIDDING_STRATEGY = 5 + AD_GROUP = 6 + AD_GROUP_CRITERION = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/bidding_strategy_status.py b/google/ads/googleads/v12/enums/types/bidding_strategy_status.py new file mode 100644 index 000000000..2e118fdf0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/bidding_strategy_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategyStatusEnum",}, +) + + +class BiddingStrategyStatusEnum(proto.Message): + r"""Message describing BiddingStrategy statuses. + """ + + class BiddingStrategyStatus(proto.Enum): + r"""The possible statuses of a BiddingStrategy.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/bidding_strategy_system_status.py b/google/ads/googleads/v12/enums/types/bidding_strategy_system_status.py new file mode 100644 index 000000000..16d3a7af2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/bidding_strategy_system_status.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategySystemStatusEnum",}, +) + + +class BiddingStrategySystemStatusEnum(proto.Message): + r"""Message describing BiddingStrategy system statuses. + """ + + class BiddingStrategySystemStatus(proto.Enum): + r"""The possible system statuses of a BiddingStrategy.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + LEARNING_NEW = 3 + LEARNING_SETTING_CHANGE = 4 + LEARNING_BUDGET_CHANGE = 5 + LEARNING_COMPOSITION_CHANGE = 6 + LEARNING_CONVERSION_TYPE_CHANGE = 7 + LEARNING_CONVERSION_SETTING_CHANGE = 8 + LIMITED_BY_CPC_BID_CEILING = 9 + LIMITED_BY_CPC_BID_FLOOR = 10 + LIMITED_BY_DATA = 11 + LIMITED_BY_BUDGET = 12 + LIMITED_BY_LOW_PRIORITY_SPEND = 13 + LIMITED_BY_LOW_QUALITY = 14 + LIMITED_BY_INVENTORY = 15 + MISCONFIGURED_ZERO_ELIGIBILITY = 16 + MISCONFIGURED_CONVERSION_TYPES = 17 + MISCONFIGURED_CONVERSION_SETTINGS = 18 + MISCONFIGURED_SHARED_BUDGET = 19 + MISCONFIGURED_STRATEGY_TYPE = 20 + PAUSED = 21 + UNAVAILABLE = 22 + MULTIPLE_LEARNING = 23 + MULTIPLE_LIMITED = 24 + MULTIPLE_MISCONFIGURED = 25 + MULTIPLE = 26 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/bidding_strategy_type.py b/google/ads/googleads/v12/enums/types/bidding_strategy_type.py new file mode 100644 index 000000000..f91c5d292 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/bidding_strategy_type.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategyTypeEnum",}, +) + + +class BiddingStrategyTypeEnum(proto.Message): + r"""Container for enum describing possible bidding strategy + types. + + """ + + class BiddingStrategyType(proto.Enum): + r"""Enum describing possible bidding strategy types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + COMMISSION = 16 + ENHANCED_CPC = 2 + INVALID = 17 + MANUAL_CPA = 18 + MANUAL_CPC = 3 + MANUAL_CPM = 4 + MANUAL_CPV = 13 + MAXIMIZE_CONVERSIONS = 10 + MAXIMIZE_CONVERSION_VALUE = 11 + PAGE_ONE_PROMOTED = 5 + PERCENT_CPC = 12 + TARGET_CPA = 6 + TARGET_CPM = 14 + TARGET_IMPRESSION_SHARE = 15 + TARGET_OUTRANK_SHARE = 7 + TARGET_ROAS = 8 + TARGET_SPEND = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/billing_setup_status.py b/google/ads/googleads/v12/enums/types/billing_setup_status.py new file mode 100644 index 000000000..44d434764 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/billing_setup_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BillingSetupStatusEnum",}, +) + + +class BillingSetupStatusEnum(proto.Message): + r"""Message describing BillingSetup statuses. + """ + + class BillingSetupStatus(proto.Enum): + r"""The possible statuses of a BillingSetup.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + APPROVED_HELD = 3 + APPROVED = 4 + CANCELLED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/brand_safety_suitability.py b/google/ads/googleads/v12/enums/types/brand_safety_suitability.py new file mode 100644 index 000000000..aa37f3fe0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/brand_safety_suitability.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BrandSafetySuitabilityEnum",}, +) + + +class BrandSafetySuitabilityEnum(proto.Message): + r"""Container for enum with 3-Tier brand safety suitability + control. + + """ + + class BrandSafetySuitability(proto.Enum): + r"""3-Tier brand safety suitability control.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXPANDED_INVENTORY = 2 + STANDARD_INVENTORY = 3 + LIMITED_INVENTORY = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/budget_campaign_association_status.py b/google/ads/googleads/v12/enums/types/budget_campaign_association_status.py new file mode 100644 index 000000000..b8f9a7f63 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/budget_campaign_association_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BudgetCampaignAssociationStatusEnum",}, +) + + +class BudgetCampaignAssociationStatusEnum(proto.Message): + r"""Message describing the status of the association between the + Budget and the Campaign. + + """ + + class BudgetCampaignAssociationStatus(proto.Enum): + r"""Possible statuses of the association between the Budget and + the Campaign. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/budget_delivery_method.py b/google/ads/googleads/v12/enums/types/budget_delivery_method.py new file mode 100644 index 000000000..ece73550c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/budget_delivery_method.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BudgetDeliveryMethodEnum",}, +) + + +class BudgetDeliveryMethodEnum(proto.Message): + r"""Message describing Budget delivery methods. A delivery method + determines the rate at which the Budget is spent. + + """ + + class BudgetDeliveryMethod(proto.Enum): + r"""Possible delivery methods of a Budget.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + STANDARD = 2 + ACCELERATED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/budget_period.py b/google/ads/googleads/v12/enums/types/budget_period.py new file mode 100644 index 000000000..c2744ce48 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/budget_period.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BudgetPeriodEnum",}, +) + + +class BudgetPeriodEnum(proto.Message): + r"""Message describing Budget period. + """ + + class BudgetPeriod(proto.Enum): + r"""Possible period of a Budget.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DAILY = 2 + CUSTOM_PERIOD = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/budget_status.py b/google/ads/googleads/v12/enums/types/budget_status.py new file mode 100644 index 000000000..d60c8f921 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/budget_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BudgetStatusEnum",}, +) + + +class BudgetStatusEnum(proto.Message): + r"""Message describing a Budget status + """ + + class BudgetStatus(proto.Enum): + r"""Possible statuses of a Budget.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/budget_type.py b/google/ads/googleads/v12/enums/types/budget_type.py new file mode 100644 index 000000000..54f56bbac --- /dev/null +++ b/google/ads/googleads/v12/enums/types/budget_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"BudgetTypeEnum",}, +) + + +class BudgetTypeEnum(proto.Message): + r"""Describes Budget types. + """ + + class BudgetType(proto.Enum): + r"""Possible Budget types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + STANDARD = 2 + FIXED_CPA = 4 + SMART_CAMPAIGN = 5 + LOCAL_SERVICES = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/call_conversion_reporting_state.py b/google/ads/googleads/v12/enums/types/call_conversion_reporting_state.py new file mode 100644 index 000000000..b8c9a87b8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/call_conversion_reporting_state.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CallConversionReportingStateEnum",}, +) + + +class CallConversionReportingStateEnum(proto.Message): + r"""Container for enum describing possible data types for call + conversion reporting state. + + """ + + class CallConversionReportingState(proto.Enum): + r"""Possible data types for a call conversion action state.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DISABLED = 2 + USE_ACCOUNT_LEVEL_CALL_CONVERSION_ACTION = 3 + USE_RESOURCE_LEVEL_CALL_CONVERSION_ACTION = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/call_placeholder_field.py b/google/ads/googleads/v12/enums/types/call_placeholder_field.py new file mode 100644 index 000000000..f0f3d90b8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/call_placeholder_field.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CallPlaceholderFieldEnum",}, +) + + +class CallPlaceholderFieldEnum(proto.Message): + r"""Values for Call placeholder fields. + """ + + class CallPlaceholderField(proto.Enum): + r"""Possible values for Call placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PHONE_NUMBER = 2 + COUNTRY_CODE = 3 + TRACKED = 4 + CONVERSION_TYPE_ID = 5 + CONVERSION_REPORTING_STATE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/call_to_action_type.py b/google/ads/googleads/v12/enums/types/call_to_action_type.py new file mode 100644 index 000000000..e7002e82a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/call_to_action_type.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CallToActionTypeEnum",}, +) + + +class CallToActionTypeEnum(proto.Message): + r"""Container for enum describing the call to action types. + """ + + class CallToActionType(proto.Enum): + r"""Enum describing possible types of call to action.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LEARN_MORE = 2 + GET_QUOTE = 3 + APPLY_NOW = 4 + SIGN_UP = 5 + CONTACT_US = 6 + SUBSCRIBE = 7 + DOWNLOAD = 8 + BOOK_NOW = 9 + SHOP_NOW = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/call_tracking_display_location.py b/google/ads/googleads/v12/enums/types/call_tracking_display_location.py new file mode 100644 index 000000000..97fc8a79d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/call_tracking_display_location.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CallTrackingDisplayLocationEnum",}, +) + + +class CallTrackingDisplayLocationEnum(proto.Message): + r"""Container for enum describing possible call tracking display + locations. + + """ + + class CallTrackingDisplayLocation(proto.Enum): + r"""Possible call tracking display locations.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD = 2 + LANDING_PAGE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/call_type.py b/google/ads/googleads/v12/enums/types/call_type.py new file mode 100644 index 000000000..16c3884b4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/call_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CallTypeEnum",}, +) + + +class CallTypeEnum(proto.Message): + r"""Container for enum describing possible types of property from + where the call was made. + + """ + + class CallType(proto.Enum): + r"""Possible types of property from where the call was made.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MANUALLY_DIALED = 2 + HIGH_END_MOBILE_SEARCH = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/callout_placeholder_field.py b/google/ads/googleads/v12/enums/types/callout_placeholder_field.py new file mode 100644 index 000000000..4f479ccb2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/callout_placeholder_field.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CalloutPlaceholderFieldEnum",}, +) + + +class CalloutPlaceholderFieldEnum(proto.Message): + r"""Values for Callout placeholder fields. + """ + + class CalloutPlaceholderField(proto.Enum): + r"""Possible values for Callout placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CALLOUT_TEXT = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_criterion_status.py b/google/ads/googleads/v12/enums/types/campaign_criterion_status.py new file mode 100644 index 000000000..1f4507542 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_criterion_status.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignCriterionStatusEnum",}, +) + + +class CampaignCriterionStatusEnum(proto.Message): + r"""Message describing CampaignCriterion statuses. + """ + + class CampaignCriterionStatus(proto.Enum): + r"""The possible statuses of a CampaignCriterion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_draft_status.py b/google/ads/googleads/v12/enums/types/campaign_draft_status.py new file mode 100644 index 000000000..783f4da06 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_draft_status.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignDraftStatusEnum",}, +) + + +class CampaignDraftStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a campaign + draft. + + """ + + class CampaignDraftStatus(proto.Enum): + r"""Possible statuses of a campaign draft.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PROPOSED = 2 + REMOVED = 3 + PROMOTING = 5 + PROMOTED = 4 + PROMOTE_FAILED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_experiment_type.py b/google/ads/googleads/v12/enums/types/campaign_experiment_type.py new file mode 100644 index 000000000..b91ac6e5c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_experiment_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignExperimentTypeEnum",}, +) + + +class CampaignExperimentTypeEnum(proto.Message): + r"""Container for enum describing campaign experiment type. + """ + + class CampaignExperimentType(proto.Enum): + r"""Indicates if this campaign is a normal campaign, + a draft campaign, or an experiment campaign. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + BASE = 2 + DRAFT = 3 + EXPERIMENT = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_group_status.py b/google/ads/googleads/v12/enums/types/campaign_group_status.py new file mode 100644 index 000000000..daf5b242b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_group_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignGroupStatusEnum",}, +) + + +class CampaignGroupStatusEnum(proto.Message): + r"""Message describing CampaignGroup statuses. + """ + + class CampaignGroupStatus(proto.Enum): + r"""Possible statuses of a CampaignGroup.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_primary_status.py b/google/ads/googleads/v12/enums/types/campaign_primary_status.py new file mode 100644 index 000000000..d99f0fe0d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_primary_status.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignPrimaryStatusEnum",}, +) + + +class CampaignPrimaryStatusEnum(proto.Message): + r"""Container for enum describing possible campaign primary + status. + + """ + + class CampaignPrimaryStatus(proto.Enum): + r"""Enum describing the possible campaign primary status. + Provides insight into why a campaign is not serving or not + serving optimally. Modification to the campaign and its related + entities might take a while to be reflected in this status. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ELIGIBLE = 2 + PAUSED = 3 + REMOVED = 4 + ENDED = 5 + PENDING = 6 + MISCONFIGURED = 7 + LIMITED = 8 + LEARNING = 9 + NOT_ELIGIBLE = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_primary_status_reason.py b/google/ads/googleads/v12/enums/types/campaign_primary_status_reason.py new file mode 100644 index 000000000..bbaf57ef0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_primary_status_reason.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignPrimaryStatusReasonEnum",}, +) + + +class CampaignPrimaryStatusReasonEnum(proto.Message): + r"""Container for enum describing possible campaign primary + status reasons. + + """ + + class CampaignPrimaryStatusReason(proto.Enum): + r"""Enum describing the possible campaign primary status reasons. + Provides insight into why a campaign is not serving or not + serving optimally. These reasons are aggregated to determine an + overall campaign primary status. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN_REMOVED = 2 + CAMPAIGN_PAUSED = 3 + CAMPAIGN_PENDING = 4 + CAMPAIGN_ENDED = 5 + CAMPAIGN_DRAFT = 6 + BIDDING_STRATEGY_MISCONFIGURED = 7 + BIDDING_STRATEGY_LIMITED = 8 + BIDDING_STRATEGY_LEARNING = 9 + BIDDING_STRATEGY_CONSTRAINED = 10 + BUDGET_CONSTRAINED = 11 + BUDGET_MISCONFIGURED = 12 + SEARCH_VOLUME_LIMITED = 13 + AD_GROUPS_PAUSED = 14 + NO_AD_GROUPS = 15 + KEYWORDS_PAUSED = 16 + NO_KEYWORDS = 17 + AD_GROUP_ADS_PAUSED = 18 + NO_AD_GROUP_ADS = 19 + HAS_ADS_LIMITED_BY_POLICY = 20 + HAS_ADS_DISAPPROVED = 21 + MOST_ADS_UNDER_REVIEW = 22 + MISSING_LEAD_FORM_EXTENSION = 23 + MISSING_CALL_EXTENSION = 24 + LEAD_FORM_EXTENSION_UNDER_REVIEW = 25 + LEAD_FORM_EXTENSION_DISAPPROVED = 26 + CALL_EXTENSION_UNDER_REVIEW = 27 + CALL_EXTENSION_DISAPPROVED = 28 + NO_MOBILE_APPLICATION_AD_GROUP_CRITERIA = 29 + CAMPAIGN_GROUP_PAUSED = 30 + CAMPAIGN_GROUP_ALL_GROUP_BUDGETS_ENDED = 31 + APP_NOT_RELEASED = 32 + APP_PARTIALLY_RELEASED = 33 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_serving_status.py b/google/ads/googleads/v12/enums/types/campaign_serving_status.py new file mode 100644 index 000000000..1c5d50123 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_serving_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignServingStatusEnum",}, +) + + +class CampaignServingStatusEnum(proto.Message): + r"""Message describing Campaign serving statuses. + """ + + class CampaignServingStatus(proto.Enum): + r"""Possible serving statuses of a campaign.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SERVING = 2 + NONE = 3 + ENDED = 4 + PENDING = 5 + SUSPENDED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_shared_set_status.py b/google/ads/googleads/v12/enums/types/campaign_shared_set_status.py new file mode 100644 index 000000000..caba37944 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_shared_set_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignSharedSetStatusEnum",}, +) + + +class CampaignSharedSetStatusEnum(proto.Message): + r"""Container for enum describing types of campaign shared set + statuses. + + """ + + class CampaignSharedSetStatus(proto.Enum): + r"""Enum listing the possible campaign shared set statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/campaign_status.py b/google/ads/googleads/v12/enums/types/campaign_status.py new file mode 100644 index 000000000..a67f0f699 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/campaign_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CampaignStatusEnum",}, +) + + +class CampaignStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + campaign. + + """ + + class CampaignStatus(proto.Enum): + r"""Possible statuses of a campaign.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PAUSED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/chain_relationship_type.py b/google/ads/googleads/v12/enums/types/chain_relationship_type.py new file mode 100644 index 000000000..4cbd30c63 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/chain_relationship_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ChainRelationshipTypeEnum",}, +) + + +class ChainRelationshipTypeEnum(proto.Message): + r"""Container for enum describing possible types of a + relationship. + + """ + + class ChainRelationshipType(proto.Enum): + r"""Possible types of a relationship.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AUTO_DEALERS = 2 + GENERAL_RETAILERS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/change_client_type.py b/google/ads/googleads/v12/enums/types/change_client_type.py new file mode 100644 index 000000000..a1ab7c319 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/change_client_type.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ChangeClientTypeEnum",}, +) + + +class ChangeClientTypeEnum(proto.Message): + r"""Container for enum describing the sources that the change + event resource was made through. + + """ + + class ChangeClientType(proto.Enum): + r"""The source that the change_event resource was made through.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + GOOGLE_ADS_WEB_CLIENT = 2 + GOOGLE_ADS_AUTOMATED_RULE = 3 + GOOGLE_ADS_SCRIPTS = 4 + GOOGLE_ADS_BULK_UPLOAD = 5 + GOOGLE_ADS_API = 6 + GOOGLE_ADS_EDITOR = 7 + GOOGLE_ADS_MOBILE_APP = 8 + GOOGLE_ADS_RECOMMENDATIONS = 9 + SEARCH_ADS_360_SYNC = 10 + SEARCH_ADS_360_POST = 11 + INTERNAL_TOOL = 12 + OTHER = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/change_event_resource_type.py b/google/ads/googleads/v12/enums/types/change_event_resource_type.py new file mode 100644 index 000000000..501bea3e5 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/change_event_resource_type.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ChangeEventResourceTypeEnum",}, +) + + +class ChangeEventResourceTypeEnum(proto.Message): + r"""Container for enum describing supported resource types for + the ChangeEvent resource. + + """ + + class ChangeEventResourceType(proto.Enum): + r"""Enum listing the resource types support by the ChangeEvent + resource. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + AD = 2 + AD_GROUP = 3 + AD_GROUP_CRITERION = 4 + CAMPAIGN = 5 + CAMPAIGN_BUDGET = 6 + AD_GROUP_BID_MODIFIER = 7 + CAMPAIGN_CRITERION = 8 + FEED = 9 + FEED_ITEM = 10 + CAMPAIGN_FEED = 11 + AD_GROUP_FEED = 12 + AD_GROUP_AD = 13 + ASSET = 14 + CUSTOMER_ASSET = 15 + CAMPAIGN_ASSET = 16 + AD_GROUP_ASSET = 17 + ASSET_SET = 18 + ASSET_SET_ASSET = 19 + CAMPAIGN_ASSET_SET = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/change_status_operation.py b/google/ads/googleads/v12/enums/types/change_status_operation.py new file mode 100644 index 000000000..2dc514c33 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/change_status_operation.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ChangeStatusOperationEnum",}, +) + + +class ChangeStatusOperationEnum(proto.Message): + r"""Container for enum describing operations for the ChangeStatus + resource. + + """ + + class ChangeStatusOperation(proto.Enum): + r"""Status of the changed resource""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADDED = 2 + CHANGED = 3 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/change_status_resource_type.py b/google/ads/googleads/v12/enums/types/change_status_resource_type.py new file mode 100644 index 000000000..657ca47bd --- /dev/null +++ b/google/ads/googleads/v12/enums/types/change_status_resource_type.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ChangeStatusResourceTypeEnum",}, +) + + +class ChangeStatusResourceTypeEnum(proto.Message): + r"""Container for enum describing supported resource types for + the ChangeStatus resource. + + """ + + class ChangeStatusResourceType(proto.Enum): + r"""Enum listing the resource types support by the ChangeStatus + resource. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP = 3 + AD_GROUP_AD = 4 + AD_GROUP_CRITERION = 5 + CAMPAIGN = 6 + CAMPAIGN_CRITERION = 7 + FEED = 9 + FEED_ITEM = 10 + AD_GROUP_FEED = 11 + CAMPAIGN_FEED = 12 + AD_GROUP_BID_MODIFIER = 13 + SHARED_SET = 14 + CAMPAIGN_SHARED_SET = 15 + ASSET = 16 + CUSTOMER_ASSET = 17 + CAMPAIGN_ASSET = 18 + AD_GROUP_ASSET = 19 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/click_type.py b/google/ads/googleads/v12/enums/types/click_type.py new file mode 100644 index 000000000..1e9e36c61 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/click_type.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ClickTypeEnum",}, +) + + +class ClickTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads click types. + """ + + class ClickType(proto.Enum): + r"""Enumerates Google Ads click types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APP_DEEPLINK = 2 + BREADCRUMBS = 3 + BROADBAND_PLAN = 4 + CALL_TRACKING = 5 + CALLS = 6 + CLICK_ON_ENGAGEMENT_AD = 7 + GET_DIRECTIONS = 8 + LOCATION_EXPANSION = 9 + LOCATION_FORMAT_CALL = 10 + LOCATION_FORMAT_DIRECTIONS = 11 + LOCATION_FORMAT_IMAGE = 12 + LOCATION_FORMAT_LANDING_PAGE = 13 + LOCATION_FORMAT_MAP = 14 + LOCATION_FORMAT_STORE_INFO = 15 + LOCATION_FORMAT_TEXT = 16 + MOBILE_CALL_TRACKING = 17 + OFFER_PRINTS = 18 + OTHER = 19 + PRODUCT_EXTENSION_CLICKS = 20 + PRODUCT_LISTING_AD_CLICKS = 21 + SITELINKS = 22 + STORE_LOCATOR = 23 + URL_CLICKS = 25 + VIDEO_APP_STORE_CLICKS = 26 + VIDEO_CALL_TO_ACTION_CLICKS = 27 + VIDEO_CARD_ACTION_HEADLINE_CLICKS = 28 + VIDEO_END_CAP_CLICKS = 29 + VIDEO_WEBSITE_CLICKS = 30 + VISUAL_SITELINKS = 31 + WIRELESS_PLAN = 32 + PRODUCT_LISTING_AD_LOCAL = 33 + PRODUCT_LISTING_AD_MULTICHANNEL_LOCAL = 34 + PRODUCT_LISTING_AD_MULTICHANNEL_ONLINE = 35 + PRODUCT_LISTING_ADS_COUPON = 36 + PRODUCT_LISTING_AD_TRANSACTABLE = 37 + PRODUCT_AD_APP_DEEPLINK = 38 + SHOWCASE_AD_CATEGORY_LINK = 39 + SHOWCASE_AD_LOCAL_STOREFRONT_LINK = 40 + SHOWCASE_AD_ONLINE_PRODUCT_LINK = 42 + SHOWCASE_AD_LOCAL_PRODUCT_LINK = 43 + PROMOTION_EXTENSION = 44 + SWIPEABLE_GALLERY_AD_HEADLINE = 45 + SWIPEABLE_GALLERY_AD_SWIPES = 46 + SWIPEABLE_GALLERY_AD_SEE_MORE = 47 + SWIPEABLE_GALLERY_AD_SITELINK_ONE = 48 + SWIPEABLE_GALLERY_AD_SITELINK_TWO = 49 + SWIPEABLE_GALLERY_AD_SITELINK_THREE = 50 + SWIPEABLE_GALLERY_AD_SITELINK_FOUR = 51 + SWIPEABLE_GALLERY_AD_SITELINK_FIVE = 52 + HOTEL_PRICE = 53 + PRICE_EXTENSION = 54 + HOTEL_BOOK_ON_GOOGLE_ROOM_SELECTION = 55 + SHOPPING_COMPARISON_LISTING = 56 + CROSS_NETWORK = 57 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/combined_audience_status.py b/google/ads/googleads/v12/enums/types/combined_audience_status.py new file mode 100644 index 000000000..b61178b52 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/combined_audience_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CombinedAudienceStatusEnum",}, +) + + +class CombinedAudienceStatusEnum(proto.Message): + r"""The status of combined audience. + """ + + class CombinedAudienceStatus(proto.Enum): + r"""Enum containing possible combined audience status types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/content_label_type.py b/google/ads/googleads/v12/enums/types/content_label_type.py new file mode 100644 index 000000000..7abafa9e0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/content_label_type.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ContentLabelTypeEnum",}, +) + + +class ContentLabelTypeEnum(proto.Message): + r"""Container for enum describing content label types in + ContentLabel. + + """ + + class ContentLabelType(proto.Enum): + r"""Enum listing the content label types supported by + ContentLabel criterion. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + SEXUALLY_SUGGESTIVE = 2 + BELOW_THE_FOLD = 3 + PARKED_DOMAIN = 4 + JUVENILE = 6 + PROFANITY = 7 + TRAGEDY = 8 + VIDEO = 9 + VIDEO_RATING_DV_G = 10 + VIDEO_RATING_DV_PG = 11 + VIDEO_RATING_DV_T = 12 + VIDEO_RATING_DV_MA = 13 + VIDEO_NOT_YET_RATED = 14 + EMBEDDED_VIDEO = 15 + LIVE_STREAMING_VIDEO = 16 + SOCIAL_ISSUES = 17 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_action_category.py b/google/ads/googleads/v12/enums/types/conversion_action_category.py new file mode 100644 index 000000000..a7acd7a3b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_action_category.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionActionCategoryEnum",}, +) + + +class ConversionActionCategoryEnum(proto.Message): + r"""Container for enum describing the category of conversions + that are associated with a ConversionAction. + + """ + + class ConversionActionCategory(proto.Enum): + r"""The category of conversions that are associated with a + ConversionAction. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + DEFAULT = 2 + PAGE_VIEW = 3 + PURCHASE = 4 + SIGNUP = 5 + DOWNLOAD = 7 + ADD_TO_CART = 8 + BEGIN_CHECKOUT = 9 + SUBSCRIBE_PAID = 10 + PHONE_CALL_LEAD = 11 + IMPORTED_LEAD = 12 + SUBMIT_LEAD_FORM = 13 + BOOK_APPOINTMENT = 14 + REQUEST_QUOTE = 15 + GET_DIRECTIONS = 16 + OUTBOUND_CLICK = 17 + CONTACT = 18 + ENGAGEMENT = 19 + STORE_VISIT = 20 + STORE_SALE = 21 + QUALIFIED_LEAD = 22 + CONVERTED_LEAD = 23 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_action_counting_type.py b/google/ads/googleads/v12/enums/types/conversion_action_counting_type.py new file mode 100644 index 000000000..82a18bbe7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_action_counting_type.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionActionCountingTypeEnum",}, +) + + +class ConversionActionCountingTypeEnum(proto.Message): + r"""Container for enum describing the conversion deduplication + mode for conversion optimizer. + + """ + + class ConversionActionCountingType(proto.Enum): + r"""Indicates how conversions for this action will be counted. + For more information, see + https://support.google.com/google-ads/answer/3438531. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ONE_PER_CLICK = 2 + MANY_PER_CLICK = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_action_status.py b/google/ads/googleads/v12/enums/types/conversion_action_status.py new file mode 100644 index 000000000..c0213fb8c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_action_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionActionStatusEnum",}, +) + + +class ConversionActionStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + conversion action. + + """ + + class ConversionActionStatus(proto.Enum): + r"""Possible statuses of a conversion action.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + HIDDEN = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_action_type.py b/google/ads/googleads/v12/enums/types/conversion_action_type.py new file mode 100644 index 000000000..197213709 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_action_type.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionActionTypeEnum",}, +) + + +class ConversionActionTypeEnum(proto.Message): + r"""Container for enum describing possible types of a conversion + action. + + """ + + class ConversionActionType(proto.Enum): + r"""Possible types of a conversion action.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_CALL = 2 + CLICK_TO_CALL = 3 + GOOGLE_PLAY_DOWNLOAD = 4 + GOOGLE_PLAY_IN_APP_PURCHASE = 5 + UPLOAD_CALLS = 6 + UPLOAD_CLICKS = 7 + WEBPAGE = 8 + WEBSITE_CALL = 9 + STORE_SALES_DIRECT_UPLOAD = 10 + STORE_SALES = 11 + FIREBASE_ANDROID_FIRST_OPEN = 12 + FIREBASE_ANDROID_IN_APP_PURCHASE = 13 + FIREBASE_ANDROID_CUSTOM = 14 + FIREBASE_IOS_FIRST_OPEN = 15 + FIREBASE_IOS_IN_APP_PURCHASE = 16 + FIREBASE_IOS_CUSTOM = 17 + THIRD_PARTY_APP_ANALYTICS_ANDROID_FIRST_OPEN = 18 + THIRD_PARTY_APP_ANALYTICS_ANDROID_IN_APP_PURCHASE = 19 + THIRD_PARTY_APP_ANALYTICS_ANDROID_CUSTOM = 20 + THIRD_PARTY_APP_ANALYTICS_IOS_FIRST_OPEN = 21 + THIRD_PARTY_APP_ANALYTICS_IOS_IN_APP_PURCHASE = 22 + THIRD_PARTY_APP_ANALYTICS_IOS_CUSTOM = 23 + ANDROID_APP_PRE_REGISTRATION = 24 + ANDROID_INSTALLS_ALL_OTHER_APPS = 25 + FLOODLIGHT_ACTION = 26 + FLOODLIGHT_TRANSACTION = 27 + GOOGLE_HOSTED = 28 + LEAD_FORM_SUBMIT = 29 + SALESFORCE = 30 + SEARCH_ADS_360 = 31 + SMART_CAMPAIGN_AD_CLICKS_TO_CALL = 32 + SMART_CAMPAIGN_MAP_CLICKS_TO_CALL = 33 + SMART_CAMPAIGN_MAP_DIRECTIONS = 34 + SMART_CAMPAIGN_TRACKED_CALLS = 35 + STORE_VISITS = 36 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_adjustment_type.py b/google/ads/googleads/v12/enums/types/conversion_adjustment_type.py new file mode 100644 index 000000000..06ea0959c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_adjustment_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionAdjustmentTypeEnum",}, +) + + +class ConversionAdjustmentTypeEnum(proto.Message): + r"""Container for enum describing conversion adjustment types. + """ + + class ConversionAdjustmentType(proto.Enum): + r"""The different actions advertisers can take to adjust the + conversions that they already reported. Retractions negate a + conversion. Restatements change the value of a conversion. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + RETRACTION = 2 + RESTATEMENT = 3 + ENHANCEMENT = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_attribution_event_type.py b/google/ads/googleads/v12/enums/types/conversion_attribution_event_type.py new file mode 100644 index 000000000..3b2164dad --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_attribution_event_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionAttributionEventTypeEnum",}, +) + + +class ConversionAttributionEventTypeEnum(proto.Message): + r"""Container for enum indicating the event type the conversion + is attributed to. + + """ + + class ConversionAttributionEventType(proto.Enum): + r"""The event type of conversions that are attributed to.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + IMPRESSION = 2 + INTERACTION = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_custom_variable_status.py b/google/ads/googleads/v12/enums/types/conversion_custom_variable_status.py new file mode 100644 index 000000000..648d0b02c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_custom_variable_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionCustomVariableStatusEnum",}, +) + + +class ConversionCustomVariableStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + conversion custom variable. + + """ + + class ConversionCustomVariableStatus(proto.Enum): + r"""Possible statuses of a conversion custom variable.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACTIVATION_NEEDED = 2 + ENABLED = 3 + PAUSED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_environment_enum.py b/google/ads/googleads/v12/enums/types/conversion_environment_enum.py new file mode 100644 index 000000000..7a1c1afbb --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_environment_enum.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionEnvironmentEnum",}, +) + + +class ConversionEnvironmentEnum(proto.Message): + r"""Container for enum representing the conversion environment an + uploaded conversion was recorded on, for example, App or Web. + + """ + + class ConversionEnvironment(proto.Enum): + r"""Conversion environment of the uploaded conversion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APP = 2 + WEB = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_lag_bucket.py b/google/ads/googleads/v12/enums/types/conversion_lag_bucket.py new file mode 100644 index 000000000..22cb92527 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_lag_bucket.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionLagBucketEnum",}, +) + + +class ConversionLagBucketEnum(proto.Message): + r"""Container for enum representing the number of days between + impression and conversion. + + """ + + class ConversionLagBucket(proto.Enum): + r"""Enum representing the number of days between impression and + conversion. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + LESS_THAN_ONE_DAY = 2 + ONE_TO_TWO_DAYS = 3 + TWO_TO_THREE_DAYS = 4 + THREE_TO_FOUR_DAYS = 5 + FOUR_TO_FIVE_DAYS = 6 + FIVE_TO_SIX_DAYS = 7 + SIX_TO_SEVEN_DAYS = 8 + SEVEN_TO_EIGHT_DAYS = 9 + EIGHT_TO_NINE_DAYS = 10 + NINE_TO_TEN_DAYS = 11 + TEN_TO_ELEVEN_DAYS = 12 + ELEVEN_TO_TWELVE_DAYS = 13 + TWELVE_TO_THIRTEEN_DAYS = 14 + THIRTEEN_TO_FOURTEEN_DAYS = 15 + FOURTEEN_TO_TWENTY_ONE_DAYS = 16 + TWENTY_ONE_TO_THIRTY_DAYS = 17 + THIRTY_TO_FORTY_FIVE_DAYS = 18 + FORTY_FIVE_TO_SIXTY_DAYS = 19 + SIXTY_TO_NINETY_DAYS = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_or_adjustment_lag_bucket.py b/google/ads/googleads/v12/enums/types/conversion_or_adjustment_lag_bucket.py new file mode 100644 index 000000000..6e29b36fb --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_or_adjustment_lag_bucket.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionOrAdjustmentLagBucketEnum",}, +) + + +class ConversionOrAdjustmentLagBucketEnum(proto.Message): + r"""Container for enum representing the number of days between + the impression and the conversion or between the impression and + adjustments to the conversion. + + """ + + class ConversionOrAdjustmentLagBucket(proto.Enum): + r"""Enum representing the number of days between the impression + and the conversion or between the impression and adjustments to + the conversion. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CONVERSION_LESS_THAN_ONE_DAY = 2 + CONVERSION_ONE_TO_TWO_DAYS = 3 + CONVERSION_TWO_TO_THREE_DAYS = 4 + CONVERSION_THREE_TO_FOUR_DAYS = 5 + CONVERSION_FOUR_TO_FIVE_DAYS = 6 + CONVERSION_FIVE_TO_SIX_DAYS = 7 + CONVERSION_SIX_TO_SEVEN_DAYS = 8 + CONVERSION_SEVEN_TO_EIGHT_DAYS = 9 + CONVERSION_EIGHT_TO_NINE_DAYS = 10 + CONVERSION_NINE_TO_TEN_DAYS = 11 + CONVERSION_TEN_TO_ELEVEN_DAYS = 12 + CONVERSION_ELEVEN_TO_TWELVE_DAYS = 13 + CONVERSION_TWELVE_TO_THIRTEEN_DAYS = 14 + CONVERSION_THIRTEEN_TO_FOURTEEN_DAYS = 15 + CONVERSION_FOURTEEN_TO_TWENTY_ONE_DAYS = 16 + CONVERSION_TWENTY_ONE_TO_THIRTY_DAYS = 17 + CONVERSION_THIRTY_TO_FORTY_FIVE_DAYS = 18 + CONVERSION_FORTY_FIVE_TO_SIXTY_DAYS = 19 + CONVERSION_SIXTY_TO_NINETY_DAYS = 20 + ADJUSTMENT_LESS_THAN_ONE_DAY = 21 + ADJUSTMENT_ONE_TO_TWO_DAYS = 22 + ADJUSTMENT_TWO_TO_THREE_DAYS = 23 + ADJUSTMENT_THREE_TO_FOUR_DAYS = 24 + ADJUSTMENT_FOUR_TO_FIVE_DAYS = 25 + ADJUSTMENT_FIVE_TO_SIX_DAYS = 26 + ADJUSTMENT_SIX_TO_SEVEN_DAYS = 27 + ADJUSTMENT_SEVEN_TO_EIGHT_DAYS = 28 + ADJUSTMENT_EIGHT_TO_NINE_DAYS = 29 + ADJUSTMENT_NINE_TO_TEN_DAYS = 30 + ADJUSTMENT_TEN_TO_ELEVEN_DAYS = 31 + ADJUSTMENT_ELEVEN_TO_TWELVE_DAYS = 32 + ADJUSTMENT_TWELVE_TO_THIRTEEN_DAYS = 33 + ADJUSTMENT_THIRTEEN_TO_FOURTEEN_DAYS = 34 + ADJUSTMENT_FOURTEEN_TO_TWENTY_ONE_DAYS = 35 + ADJUSTMENT_TWENTY_ONE_TO_THIRTY_DAYS = 36 + ADJUSTMENT_THIRTY_TO_FORTY_FIVE_DAYS = 37 + ADJUSTMENT_FORTY_FIVE_TO_SIXTY_DAYS = 38 + ADJUSTMENT_SIXTY_TO_NINETY_DAYS = 39 + ADJUSTMENT_NINETY_TO_ONE_HUNDRED_AND_FORTY_FIVE_DAYS = 40 + CONVERSION_UNKNOWN = 41 + ADJUSTMENT_UNKNOWN = 42 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_origin.py b/google/ads/googleads/v12/enums/types/conversion_origin.py new file mode 100644 index 000000000..eac445065 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_origin.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionOriginEnum",}, +) + + +class ConversionOriginEnum(proto.Message): + r"""Container for enum describing possible conversion origins. + """ + + class ConversionOrigin(proto.Enum): + r"""The possible places where a conversion can occur.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + WEBSITE = 2 + GOOGLE_HOSTED = 3 + APP = 4 + CALL_FROM_ADS = 5 + STORE = 6 + YOUTUBE_HOSTED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_tracking_status_enum.py b/google/ads/googleads/v12/enums/types/conversion_tracking_status_enum.py new file mode 100644 index 000000000..d90ca974a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_tracking_status_enum.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionTrackingStatusEnum",}, +) + + +class ConversionTrackingStatusEnum(proto.Message): + r"""Container for enum representing the conversion tracking + status of the customer. + + """ + + class ConversionTrackingStatus(proto.Enum): + r"""Conversion Tracking status of the customer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_CONVERSION_TRACKED = 2 + CONVERSION_TRACKING_MANAGED_BY_SELF = 3 + CONVERSION_TRACKING_MANAGED_BY_THIS_MANAGER = 4 + CONVERSION_TRACKING_MANAGED_BY_ANOTHER_MANAGER = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_value_rule_primary_dimension.py b/google/ads/googleads/v12/enums/types/conversion_value_rule_primary_dimension.py new file mode 100644 index 000000000..1134c9470 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_value_rule_primary_dimension.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRulePrimaryDimensionEnum",}, +) + + +class ConversionValueRulePrimaryDimensionEnum(proto.Message): + r"""Container for enum describing value rule primary dimension + for stats. + + """ + + class ConversionValueRulePrimaryDimension(proto.Enum): + r"""Identifies the primary dimension for conversion value rule + stats. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_RULE_APPLIED = 2 + ORIGINAL = 3 + NEW_VS_RETURNING_USER = 4 + GEO_LOCATION = 5 + DEVICE = 6 + AUDIENCE = 7 + MULTIPLE = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_value_rule_set_status.py b/google/ads/googleads/v12/enums/types/conversion_value_rule_set_status.py new file mode 100644 index 000000000..372f6d43d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_value_rule_set_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRuleSetStatusEnum",}, +) + + +class ConversionValueRuleSetStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + conversion value rule set. + + """ + + class ConversionValueRuleSetStatus(proto.Enum): + r"""Possible statuses of a conversion value rule set.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + PAUSED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/conversion_value_rule_status.py b/google/ads/googleads/v12/enums/types/conversion_value_rule_status.py new file mode 100644 index 000000000..5a36465c0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/conversion_value_rule_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRuleStatusEnum",}, +) + + +class ConversionValueRuleStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + conversion value rule. + + """ + + class ConversionValueRuleStatus(proto.Enum): + r"""Possible statuses of a conversion value rule.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + PAUSED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/criterion_category_channel_availability_mode.py b/google/ads/googleads/v12/enums/types/criterion_category_channel_availability_mode.py new file mode 100644 index 000000000..4544090be --- /dev/null +++ b/google/ads/googleads/v12/enums/types/criterion_category_channel_availability_mode.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CriterionCategoryChannelAvailabilityModeEnum",}, +) + + +class CriterionCategoryChannelAvailabilityModeEnum(proto.Message): + r"""Describes channel availability mode for a criterion + availability - whether the availability is meant to include all + advertising channels, or a particular channel with all its + channel subtypes, or a channel with a certain subset of channel + subtypes. + + """ + + class CriterionCategoryChannelAvailabilityMode(proto.Enum): + r"""Enum containing the possible + CriterionCategoryChannelAvailabilityMode. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ALL_CHANNELS = 2 + CHANNEL_TYPE_AND_ALL_SUBTYPES = 3 + CHANNEL_TYPE_AND_SUBSET_SUBTYPES = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/criterion_category_locale_availability_mode.py b/google/ads/googleads/v12/enums/types/criterion_category_locale_availability_mode.py new file mode 100644 index 000000000..9c004a3df --- /dev/null +++ b/google/ads/googleads/v12/enums/types/criterion_category_locale_availability_mode.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CriterionCategoryLocaleAvailabilityModeEnum",}, +) + + +class CriterionCategoryLocaleAvailabilityModeEnum(proto.Message): + r"""Describes locale availability mode for a criterion + availability - whether it's available globally, or a particular + country with all languages, or a particular language with all + countries, or a country-language pair. + + """ + + class CriterionCategoryLocaleAvailabilityMode(proto.Enum): + r"""Enum containing the possible + CriterionCategoryLocaleAvailabilityMode. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ALL_LOCALES = 2 + COUNTRY_AND_ALL_LANGUAGES = 3 + LANGUAGE_AND_ALL_COUNTRIES = 4 + COUNTRY_AND_LANGUAGE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/criterion_system_serving_status.py b/google/ads/googleads/v12/enums/types/criterion_system_serving_status.py new file mode 100644 index 000000000..90dea62c6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/criterion_system_serving_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CriterionSystemServingStatusEnum",}, +) + + +class CriterionSystemServingStatusEnum(proto.Message): + r"""Container for enum describing possible criterion system + serving statuses. + + """ + + class CriterionSystemServingStatus(proto.Enum): + r"""Enumerates criterion system serving statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ELIGIBLE = 2 + RARELY_SERVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/criterion_type.py b/google/ads/googleads/v12/enums/types/criterion_type.py new file mode 100644 index 000000000..3b76c9eaf --- /dev/null +++ b/google/ads/googleads/v12/enums/types/criterion_type.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CriterionTypeEnum",}, +) + + +class CriterionTypeEnum(proto.Message): + r"""The possible types of a criterion. + """ + + class CriterionType(proto.Enum): + r"""Enum describing possible criterion types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + KEYWORD = 2 + PLACEMENT = 3 + MOBILE_APP_CATEGORY = 4 + MOBILE_APPLICATION = 5 + DEVICE = 6 + LOCATION = 7 + LISTING_GROUP = 8 + AD_SCHEDULE = 9 + AGE_RANGE = 10 + GENDER = 11 + INCOME_RANGE = 12 + PARENTAL_STATUS = 13 + YOUTUBE_VIDEO = 14 + YOUTUBE_CHANNEL = 15 + USER_LIST = 16 + PROXIMITY = 17 + TOPIC = 18 + LISTING_SCOPE = 19 + LANGUAGE = 20 + IP_BLOCK = 21 + CONTENT_LABEL = 22 + CARRIER = 23 + USER_INTEREST = 24 + WEBPAGE = 25 + OPERATING_SYSTEM_VERSION = 26 + APP_PAYMENT_MODEL = 27 + MOBILE_DEVICE = 28 + CUSTOM_AFFINITY = 29 + CUSTOM_INTENT = 30 + LOCATION_GROUP = 31 + CUSTOM_AUDIENCE = 32 + COMBINED_AUDIENCE = 33 + KEYWORD_THEME = 34 + AUDIENCE = 35 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_audience_member_type.py b/google/ads/googleads/v12/enums/types/custom_audience_member_type.py new file mode 100644 index 000000000..ae1e7d1fc --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_audience_member_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomAudienceMemberTypeEnum",}, +) + + +class CustomAudienceMemberTypeEnum(proto.Message): + r"""The type of custom audience member. + """ + + class CustomAudienceMemberType(proto.Enum): + r"""Enum containing possible custom audience member types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + KEYWORD = 2 + URL = 3 + PLACE_CATEGORY = 4 + APP = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_audience_status.py b/google/ads/googleads/v12/enums/types/custom_audience_status.py new file mode 100644 index 000000000..6a440b0a3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_audience_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomAudienceStatusEnum",}, +) + + +class CustomAudienceStatusEnum(proto.Message): + r"""The status of custom audience. + """ + + class CustomAudienceStatus(proto.Enum): + r"""Enum containing possible custom audience statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_audience_type.py b/google/ads/googleads/v12/enums/types/custom_audience_type.py new file mode 100644 index 000000000..aa96438cc --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_audience_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomAudienceTypeEnum",}, +) + + +class CustomAudienceTypeEnum(proto.Message): + r"""The types of custom audience. + """ + + class CustomAudienceType(proto.Enum): + r"""Enum containing possible custom audience types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AUTO = 2 + INTEREST = 3 + PURCHASE_INTENT = 4 + SEARCH = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_conversion_goal_status.py b/google/ads/googleads/v12/enums/types/custom_conversion_goal_status.py new file mode 100644 index 000000000..edfb026b8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_conversion_goal_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomConversionGoalStatusEnum",}, +) + + +class CustomConversionGoalStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a custom + conversion goal. + + """ + + class CustomConversionGoalStatus(proto.Enum): + r"""The possible statuses of a custom conversion goal.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_interest_member_type.py b/google/ads/googleads/v12/enums/types/custom_interest_member_type.py new file mode 100644 index 000000000..ed27cc3ac --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_interest_member_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomInterestMemberTypeEnum",}, +) + + +class CustomInterestMemberTypeEnum(proto.Message): + r"""The types of custom interest member, either KEYWORD or URL. + """ + + class CustomInterestMemberType(proto.Enum): + r"""Enum containing possible custom interest member types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + KEYWORD = 2 + URL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_interest_status.py b/google/ads/googleads/v12/enums/types/custom_interest_status.py new file mode 100644 index 000000000..aabcec98b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_interest_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomInterestStatusEnum",}, +) + + +class CustomInterestStatusEnum(proto.Message): + r"""The status of custom interest. + """ + + class CustomInterestStatus(proto.Enum): + r"""Enum containing possible custom interest types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_interest_type.py b/google/ads/googleads/v12/enums/types/custom_interest_type.py new file mode 100644 index 000000000..763f1fd14 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_interest_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomInterestTypeEnum",}, +) + + +class CustomInterestTypeEnum(proto.Message): + r"""The types of custom interest. + """ + + class CustomInterestType(proto.Enum): + r"""Enum containing possible custom interest types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOM_AFFINITY = 2 + CUSTOM_INTENT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/custom_placeholder_field.py b/google/ads/googleads/v12/enums/types/custom_placeholder_field.py new file mode 100644 index 000000000..2f8b442b5 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/custom_placeholder_field.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomPlaceholderFieldEnum",}, +) + + +class CustomPlaceholderFieldEnum(proto.Message): + r"""Values for Custom placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class CustomPlaceholderField(proto.Enum): + r"""Possible values for Custom placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ID = 2 + ID2 = 3 + ITEM_TITLE = 4 + ITEM_SUBTITLE = 5 + ITEM_DESCRIPTION = 6 + ITEM_ADDRESS = 7 + PRICE = 8 + FORMATTED_PRICE = 9 + SALE_PRICE = 10 + FORMATTED_SALE_PRICE = 11 + IMAGE_URL = 12 + ITEM_CATEGORY = 13 + FINAL_URLS = 14 + FINAL_MOBILE_URLS = 15 + TRACKING_URL = 16 + CONTEXTUAL_KEYWORDS = 17 + ANDROID_APP_LINK = 18 + SIMILAR_IDS = 19 + IOS_APP_LINK = 20 + IOS_APP_STORE_ID = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customer_match_upload_key_type.py b/google/ads/googleads/v12/enums/types/customer_match_upload_key_type.py new file mode 100644 index 000000000..832f685a8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customer_match_upload_key_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomerMatchUploadKeyTypeEnum",}, +) + + +class CustomerMatchUploadKeyTypeEnum(proto.Message): + r"""Indicates what type of data are the user list's members + matched from. + + """ + + class CustomerMatchUploadKeyType(proto.Enum): + r"""Enum describing possible customer match upload key types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CONTACT_INFO = 2 + CRM_ID = 3 + MOBILE_ADVERTISING_ID = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py b/google/ads/googleads/v12/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py new file mode 100644 index 000000000..109efe103 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomerPayPerConversionEligibilityFailureReasonEnum",}, +) + + +class CustomerPayPerConversionEligibilityFailureReasonEnum(proto.Message): + r"""Container for enum describing reasons why a customer is not + eligible to use PaymentMode.CONVERSIONS. + + """ + + class CustomerPayPerConversionEligibilityFailureReason(proto.Enum): + r"""Enum describing possible reasons a customer is not eligible + to use PaymentMode.CONVERSIONS. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_ENOUGH_CONVERSIONS = 2 + CONVERSION_LAG_TOO_HIGH = 3 + HAS_CAMPAIGN_WITH_SHARED_BUDGET = 4 + HAS_UPLOAD_CLICKS_CONVERSION = 5 + AVERAGE_DAILY_SPEND_TOO_HIGH = 6 + ANALYSIS_NOT_COMPLETE = 7 + OTHER = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customer_status.py b/google/ads/googleads/v12/enums/types/customer_status.py new file mode 100644 index 000000000..bd358abd5 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customer_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomerStatusEnum",}, +) + + +class CustomerStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + customer. + + """ + + class CustomerStatus(proto.Enum): + r"""Possible statuses of a customer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + CANCELED = 3 + SUSPENDED = 4 + CLOSED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customizer_attribute_status.py b/google/ads/googleads/v12/enums/types/customizer_attribute_status.py new file mode 100644 index 000000000..8d9305c16 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customizer_attribute_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomizerAttributeStatusEnum",}, +) + + +class CustomizerAttributeStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + customizer attribute. + + """ + + class CustomizerAttributeStatus(proto.Enum): + r"""The possible statuses of a customizer attribute.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customizer_attribute_type.py b/google/ads/googleads/v12/enums/types/customizer_attribute_type.py new file mode 100644 index 000000000..1ff35be94 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customizer_attribute_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomizerAttributeTypeEnum",}, +) + + +class CustomizerAttributeTypeEnum(proto.Message): + r"""Container for enum describing possible types of a customizer + attribute. + + """ + + class CustomizerAttributeType(proto.Enum): + r"""The possible types of a customizer attribute.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TEXT = 2 + NUMBER = 3 + PRICE = 4 + PERCENT = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/customizer_value_status.py b/google/ads/googleads/v12/enums/types/customizer_value_status.py new file mode 100644 index 000000000..0ea052255 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/customizer_value_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"CustomizerValueStatusEnum",}, +) + + +class CustomizerValueStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a + customizer value. + + """ + + class CustomizerValueStatus(proto.Enum): + r"""The possible statuses of a customizer value.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/data_driven_model_status.py b/google/ads/googleads/v12/enums/types/data_driven_model_status.py new file mode 100644 index 000000000..b60b5da9a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/data_driven_model_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DataDrivenModelStatusEnum",}, +) + + +class DataDrivenModelStatusEnum(proto.Message): + r"""Container for enum indicating data driven model status. + """ + + class DataDrivenModelStatus(proto.Enum): + r"""Enumerates data driven model statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AVAILABLE = 2 + STALE = 3 + EXPIRED = 4 + NEVER_GENERATED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/day_of_week.py b/google/ads/googleads/v12/enums/types/day_of_week.py new file mode 100644 index 000000000..f62377ca3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/day_of_week.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DayOfWeekEnum",}, +) + + +class DayOfWeekEnum(proto.Message): + r"""Container for enumeration of days of the week, for example, + "Monday". + + """ + + class DayOfWeek(proto.Enum): + r"""Enumerates days of the week, for example, "Monday".""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MONDAY = 2 + TUESDAY = 3 + WEDNESDAY = 4 + THURSDAY = 5 + FRIDAY = 6 + SATURDAY = 7 + SUNDAY = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/device.py b/google/ads/googleads/v12/enums/types/device.py new file mode 100644 index 000000000..88f72e384 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/device.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DeviceEnum",}, +) + + +class DeviceEnum(proto.Message): + r"""Container for enumeration of Google Ads devices available for + targeting. + + """ + + class Device(proto.Enum): + r"""Enumerates Google Ads devices available for targeting.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MOBILE = 2 + TABLET = 3 + DESKTOP = 4 + CONNECTED_TV = 6 + OTHER = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/display_ad_format_setting.py b/google/ads/googleads/v12/enums/types/display_ad_format_setting.py new file mode 100644 index 000000000..f953f3168 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/display_ad_format_setting.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DisplayAdFormatSettingEnum",}, +) + + +class DisplayAdFormatSettingEnum(proto.Message): + r"""Container for display ad format settings. + """ + + class DisplayAdFormatSetting(proto.Enum): + r"""Enumerates display ad format settings.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ALL_FORMATS = 2 + NON_NATIVE = 3 + NATIVE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/display_upload_product_type.py b/google/ads/googleads/v12/enums/types/display_upload_product_type.py new file mode 100644 index 000000000..25a50c0b3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/display_upload_product_type.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DisplayUploadProductTypeEnum",}, +) + + +class DisplayUploadProductTypeEnum(proto.Message): + r"""Container for display upload product types. Product types + that have the word "DYNAMIC" in them must be associated with a + campaign that has a dynamic remarketing feed. See + https://support.google.com/google-ads/answer/6053288 for more + info about dynamic remarketing. Other product types are regarded + as "static" and do not have this requirement. + + """ + + class DisplayUploadProductType(proto.Enum): + r"""Enumerates display upload product types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + HTML5_UPLOAD_AD = 2 + DYNAMIC_HTML5_EDUCATION_AD = 3 + DYNAMIC_HTML5_FLIGHT_AD = 4 + DYNAMIC_HTML5_HOTEL_RENTAL_AD = 5 + DYNAMIC_HTML5_JOB_AD = 6 + DYNAMIC_HTML5_LOCAL_AD = 7 + DYNAMIC_HTML5_REAL_ESTATE_AD = 8 + DYNAMIC_HTML5_CUSTOM_AD = 9 + DYNAMIC_HTML5_TRAVEL_AD = 10 + DYNAMIC_HTML5_HOTEL_AD = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/distance_bucket.py b/google/ads/googleads/v12/enums/types/distance_bucket.py new file mode 100644 index 000000000..a8832fcf7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/distance_bucket.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DistanceBucketEnum",}, +) + + +class DistanceBucketEnum(proto.Message): + r"""Container for distance buckets of a user's distance from an + advertiser's location extension. + + """ + + class DistanceBucket(proto.Enum): + r"""The distance bucket for a user's distance from an + advertiser's location extension. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + WITHIN_700M = 2 + WITHIN_1KM = 3 + WITHIN_5KM = 4 + WITHIN_10KM = 5 + WITHIN_15KM = 6 + WITHIN_20KM = 7 + WITHIN_25KM = 8 + WITHIN_30KM = 9 + WITHIN_35KM = 10 + WITHIN_40KM = 11 + WITHIN_45KM = 12 + WITHIN_50KM = 13 + WITHIN_55KM = 14 + WITHIN_60KM = 15 + WITHIN_65KM = 16 + BEYOND_65KM = 17 + WITHIN_0_7MILES = 18 + WITHIN_1MILE = 19 + WITHIN_5MILES = 20 + WITHIN_10MILES = 21 + WITHIN_15MILES = 22 + WITHIN_20MILES = 23 + WITHIN_25MILES = 24 + WITHIN_30MILES = 25 + WITHIN_35MILES = 26 + WITHIN_40MILES = 27 + BEYOND_40MILES = 28 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/dsa_page_feed_criterion_field.py b/google/ads/googleads/v12/enums/types/dsa_page_feed_criterion_field.py new file mode 100644 index 000000000..de946ec08 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/dsa_page_feed_criterion_field.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"DsaPageFeedCriterionFieldEnum",}, +) + + +class DsaPageFeedCriterionFieldEnum(proto.Message): + r"""Values for Dynamic Search Ad Page Feed criterion fields. + """ + + class DsaPageFeedCriterionField(proto.Enum): + r"""Possible values for Dynamic Search Ad Page Feed criterion + fields. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + PAGE_URL = 2 + LABEL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/education_placeholder_field.py b/google/ads/googleads/v12/enums/types/education_placeholder_field.py new file mode 100644 index 000000000..4708f0db6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/education_placeholder_field.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"EducationPlaceholderFieldEnum",}, +) + + +class EducationPlaceholderFieldEnum(proto.Message): + r"""Values for Education placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class EducationPlaceholderField(proto.Enum): + r"""Possible values for Education placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PROGRAM_ID = 2 + LOCATION_ID = 3 + PROGRAM_NAME = 4 + AREA_OF_STUDY = 5 + PROGRAM_DESCRIPTION = 6 + SCHOOL_NAME = 7 + ADDRESS = 8 + THUMBNAIL_IMAGE_URL = 9 + ALTERNATIVE_THUMBNAIL_IMAGE_URL = 10 + FINAL_URLS = 11 + FINAL_MOBILE_URLS = 12 + TRACKING_URL = 13 + CONTEXTUAL_KEYWORDS = 14 + ANDROID_APP_LINK = 15 + SIMILAR_PROGRAM_IDS = 16 + IOS_APP_LINK = 17 + IOS_APP_STORE_ID = 18 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/experiment_metric.py b/google/ads/googleads/v12/enums/types/experiment_metric.py new file mode 100644 index 000000000..ebf8231de --- /dev/null +++ b/google/ads/googleads/v12/enums/types/experiment_metric.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExperimentMetricEnum",}, +) + + +class ExperimentMetricEnum(proto.Message): + r"""Container for enum describing the type of experiment metric. + """ + + class ExperimentMetric(proto.Enum): + r"""The type of experiment metric.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CLICKS = 2 + IMPRESSIONS = 3 + COST = 4 + CONVERSIONS_PER_INTERACTION_RATE = 5 + COST_PER_CONVERSION = 6 + CONVERSIONS_VALUE_PER_COST = 7 + AVERAGE_CPC = 8 + CTR = 9 + INCREMENTAL_CONVERSIONS = 10 + COMPLETED_VIDEO_VIEWS = 11 + CUSTOM_ALGORITHMS = 12 + CONVERSIONS = 13 + CONVERSION_VALUE = 14 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/experiment_metric_direction.py b/google/ads/googleads/v12/enums/types/experiment_metric_direction.py new file mode 100644 index 000000000..914369cca --- /dev/null +++ b/google/ads/googleads/v12/enums/types/experiment_metric_direction.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExperimentMetricDirectionEnum",}, +) + + +class ExperimentMetricDirectionEnum(proto.Message): + r"""Container for enum describing the type of experiment metric + direction. + + """ + + class ExperimentMetricDirection(proto.Enum): + r"""The type of experiment metric direction.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_CHANGE = 2 + INCREASE = 3 + DECREASE = 4 + NO_CHANGE_OR_INCREASE = 5 + NO_CHANGE_OR_DECREASE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/experiment_status.py b/google/ads/googleads/v12/enums/types/experiment_status.py new file mode 100644 index 000000000..394746a6b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/experiment_status.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExperimentStatusEnum",}, +) + + +class ExperimentStatusEnum(proto.Message): + r"""Container for enum describing the experiment status. + """ + + class ExperimentStatus(proto.Enum): + r"""The status of the experiment.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + HALTED = 4 + PROMOTED = 5 + SETUP = 6 + INITIATED = 7 + GRADUATED = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/experiment_type.py b/google/ads/googleads/v12/enums/types/experiment_type.py new file mode 100644 index 000000000..33fc4590a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/experiment_type.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExperimentTypeEnum",}, +) + + +class ExperimentTypeEnum(proto.Message): + r"""Container for enum describing the type of experiment. + """ + + class ExperimentType(proto.Enum): + r"""The type of the experiment.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DISPLAY_AND_VIDEO_360 = 2 + AD_VARIATION = 3 + YOUTUBE_CUSTOM = 5 + DISPLAY_CUSTOM = 6 + SEARCH_CUSTOM = 7 + DISPLAY_AUTOMATED_BIDDING_STRATEGY = 8 + SEARCH_AUTOMATED_BIDDING_STRATEGY = 9 + SHOPPING_AUTOMATED_BIDDING_STRATEGY = 10 + SMART_MATCHING = 11 + HOTEL_CUSTOM = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/extension_setting_device.py b/google/ads/googleads/v12/enums/types/extension_setting_device.py new file mode 100644 index 000000000..66feb6db0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/extension_setting_device.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExtensionSettingDeviceEnum",}, +) + + +class ExtensionSettingDeviceEnum(proto.Message): + r"""Container for enum describing extension setting device types. + """ + + class ExtensionSettingDevice(proto.Enum): + r"""Possible device types for an extension setting.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MOBILE = 2 + DESKTOP = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/extension_type.py b/google/ads/googleads/v12/enums/types/extension_type.py new file mode 100644 index 000000000..9f73917c3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/extension_type.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExtensionTypeEnum",}, +) + + +class ExtensionTypeEnum(proto.Message): + r"""Container for enum describing possible data types for an + extension in an extension setting. + + """ + + class ExtensionType(proto.Enum): + r"""Possible data types for an extension in an extension setting.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NONE = 2 + APP = 3 + CALL = 4 + CALLOUT = 5 + MESSAGE = 6 + PRICE = 7 + PROMOTION = 8 + SITELINK = 10 + STRUCTURED_SNIPPET = 11 + LOCATION = 12 + AFFILIATE_LOCATION = 13 + HOTEL_CALLOUT = 15 + IMAGE = 16 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/external_conversion_source.py b/google/ads/googleads/v12/enums/types/external_conversion_source.py new file mode 100644 index 000000000..4f444482e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/external_conversion_source.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ExternalConversionSourceEnum",}, +) + + +class ExternalConversionSourceEnum(proto.Message): + r"""Container for enum describing the external conversion source + that is associated with a ConversionAction. + + """ + + class ExternalConversionSource(proto.Enum): + r"""The external conversion source that is associated with a + ConversionAction. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + WEBPAGE = 2 + ANALYTICS = 3 + UPLOAD = 4 + AD_CALL_METRICS = 5 + WEBSITE_CALL_METRICS = 6 + STORE_VISITS = 7 + ANDROID_IN_APP = 8 + IOS_IN_APP = 9 + IOS_FIRST_OPEN = 10 + APP_UNSPECIFIED = 11 + ANDROID_FIRST_OPEN = 12 + UPLOAD_CALLS = 13 + FIREBASE = 14 + CLICK_TO_CALL = 15 + SALESFORCE = 16 + STORE_SALES_CRM = 17 + STORE_SALES_PAYMENT_NETWORK = 18 + GOOGLE_PLAY = 19 + THIRD_PARTY_APP_ANALYTICS = 20 + GOOGLE_ATTRIBUTION = 21 + STORE_SALES_DIRECT_UPLOAD = 23 + STORE_SALES = 24 + SEARCH_ADS_360 = 25 + GOOGLE_HOSTED = 27 + FLOODLIGHT = 29 + ANALYTICS_SEARCH_ADS_360 = 31 + FIREBASE_SEARCH_ADS_360 = 33 + DISPLAY_AND_VIDEO_360_FLOODLIGHT = 34 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_attribute_type.py b/google/ads/googleads/v12/enums/types/feed_attribute_type.py new file mode 100644 index 000000000..9fb042f22 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_attribute_type.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedAttributeTypeEnum",}, +) + + +class FeedAttributeTypeEnum(proto.Message): + r"""Container for enum describing possible data types for a feed + attribute. + + """ + + class FeedAttributeType(proto.Enum): + r"""Possible data types for a feed attribute.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INT64 = 2 + DOUBLE = 3 + STRING = 4 + BOOLEAN = 5 + URL = 6 + DATE_TIME = 7 + INT64_LIST = 8 + DOUBLE_LIST = 9 + STRING_LIST = 10 + BOOLEAN_LIST = 11 + URL_LIST = 12 + DATE_TIME_LIST = 13 + PRICE = 14 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_quality_approval_status.py b/google/ads/googleads/v12/enums/types/feed_item_quality_approval_status.py new file mode 100644 index 000000000..f240fd03e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_quality_approval_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemQualityApprovalStatusEnum",}, +) + + +class FeedItemQualityApprovalStatusEnum(proto.Message): + r"""Container for enum describing possible quality evaluation + approval statuses of a feed item. + + """ + + class FeedItemQualityApprovalStatus(proto.Enum): + r"""The possible quality evaluation approval statuses of a feed + item. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + APPROVED = 2 + DISAPPROVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_quality_disapproval_reason.py b/google/ads/googleads/v12/enums/types/feed_item_quality_disapproval_reason.py new file mode 100644 index 000000000..bd882f976 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_quality_disapproval_reason.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemQualityDisapprovalReasonEnum",}, +) + + +class FeedItemQualityDisapprovalReasonEnum(proto.Message): + r"""Container for enum describing possible quality evaluation + disapproval reasons of a feed item. + + """ + + class FeedItemQualityDisapprovalReason(proto.Enum): + r"""The possible quality evaluation disapproval reasons of a feed + item. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + PRICE_TABLE_REPETITIVE_HEADERS = 2 + PRICE_TABLE_REPETITIVE_DESCRIPTION = 3 + PRICE_TABLE_INCONSISTENT_ROWS = 4 + PRICE_DESCRIPTION_HAS_PRICE_QUALIFIERS = 5 + PRICE_UNSUPPORTED_LANGUAGE = 6 + PRICE_TABLE_ROW_HEADER_TABLE_TYPE_MISMATCH = 7 + PRICE_TABLE_ROW_HEADER_HAS_PROMOTIONAL_TEXT = 8 + PRICE_TABLE_ROW_DESCRIPTION_NOT_RELEVANT = 9 + PRICE_TABLE_ROW_DESCRIPTION_HAS_PROMOTIONAL_TEXT = 10 + PRICE_TABLE_ROW_HEADER_DESCRIPTION_REPETITIVE = 11 + PRICE_TABLE_ROW_UNRATEABLE = 12 + PRICE_TABLE_ROW_PRICE_INVALID = 13 + PRICE_TABLE_ROW_URL_INVALID = 14 + PRICE_HEADER_OR_DESCRIPTION_HAS_PRICE = 15 + STRUCTURED_SNIPPETS_HEADER_POLICY_VIOLATED = 16 + STRUCTURED_SNIPPETS_REPEATED_VALUES = 17 + STRUCTURED_SNIPPETS_EDITORIAL_GUIDELINES = 18 + STRUCTURED_SNIPPETS_HAS_PROMOTIONAL_TEXT = 19 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_set_status.py b/google/ads/googleads/v12/enums/types/feed_item_set_status.py new file mode 100644 index 000000000..133ddcf64 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_set_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSetStatusEnum",}, +) + + +class FeedItemSetStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a feed + item set. + + """ + + class FeedItemSetStatus(proto.Enum): + r"""Possible statuses of a feed item set.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_set_string_filter_type.py b/google/ads/googleads/v12/enums/types/feed_item_set_string_filter_type.py new file mode 100644 index 000000000..304c597c7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_set_string_filter_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSetStringFilterTypeEnum",}, +) + + +class FeedItemSetStringFilterTypeEnum(proto.Message): + r"""The type of string matching to be used for a dynamic + FeedItemSet filter. + + """ + + class FeedItemSetStringFilterType(proto.Enum): + r"""describe the possible types for a FeedItemSetStringFilter.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXACT = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_status.py b/google/ads/googleads/v12/enums/types/feed_item_status.py new file mode 100644 index 000000000..0c9d678b5 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemStatusEnum",}, +) + + +class FeedItemStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a feed + item. + + """ + + class FeedItemStatus(proto.Enum): + r"""Possible statuses of a feed item.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_target_device.py b/google/ads/googleads/v12/enums/types/feed_item_target_device.py new file mode 100644 index 000000000..b5e553930 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_target_device.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemTargetDeviceEnum",}, +) + + +class FeedItemTargetDeviceEnum(proto.Message): + r"""Container for enum describing possible data types for a feed + item target device. + + """ + + class FeedItemTargetDevice(proto.Enum): + r"""Possible data types for a feed item target device.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MOBILE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_target_status.py b/google/ads/googleads/v12/enums/types/feed_item_target_status.py new file mode 100644 index 000000000..73edac80d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_target_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemTargetStatusEnum",}, +) + + +class FeedItemTargetStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a feed + item target. + + """ + + class FeedItemTargetStatus(proto.Enum): + r"""Possible statuses of a feed item target.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_target_type.py b/google/ads/googleads/v12/enums/types/feed_item_target_type.py new file mode 100644 index 000000000..7bd0e5464 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_target_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemTargetTypeEnum",}, +) + + +class FeedItemTargetTypeEnum(proto.Message): + r"""Container for enum describing possible types of a feed item + target. + + """ + + class FeedItemTargetType(proto.Enum): + r"""Possible type of a feed item target.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN = 2 + AD_GROUP = 3 + CRITERION = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_item_validation_status.py b/google/ads/googleads/v12/enums/types/feed_item_validation_status.py new file mode 100644 index 000000000..40272324f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_item_validation_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedItemValidationStatusEnum",}, +) + + +class FeedItemValidationStatusEnum(proto.Message): + r"""Container for enum describing possible validation statuses of + a feed item. + + """ + + class FeedItemValidationStatus(proto.Enum): + r"""The possible validation statuses of a feed item.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + INVALID = 3 + VALID = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_link_status.py b/google/ads/googleads/v12/enums/types/feed_link_status.py new file mode 100644 index 000000000..95ce1ad5d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_link_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedLinkStatusEnum",}, +) + + +class FeedLinkStatusEnum(proto.Message): + r"""Container for an enum describing possible statuses of a feed + link. + + """ + + class FeedLinkStatus(proto.Enum): + r"""Possible statuses of a feed link.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_mapping_criterion_type.py b/google/ads/googleads/v12/enums/types/feed_mapping_criterion_type.py new file mode 100644 index 000000000..16b015b81 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_mapping_criterion_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedMappingCriterionTypeEnum",}, +) + + +class FeedMappingCriterionTypeEnum(proto.Message): + r"""Container for enum describing possible criterion types for a + feed mapping. + + """ + + class FeedMappingCriterionType(proto.Enum): + r"""Possible placeholder types for a feed mapping.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LOCATION_EXTENSION_TARGETING = 4 + DSA_PAGE_FEED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_mapping_status.py b/google/ads/googleads/v12/enums/types/feed_mapping_status.py new file mode 100644 index 000000000..10e0bf531 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_mapping_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedMappingStatusEnum",}, +) + + +class FeedMappingStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a feed + mapping. + + """ + + class FeedMappingStatus(proto.Enum): + r"""Possible statuses of a feed mapping.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_origin.py b/google/ads/googleads/v12/enums/types/feed_origin.py new file mode 100644 index 000000000..2e8587f1a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_origin.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedOriginEnum",}, +) + + +class FeedOriginEnum(proto.Message): + r"""Container for enum describing possible values for a feed + origin. + + """ + + class FeedOrigin(proto.Enum): + r"""Possible values for a feed origin.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + USER = 2 + GOOGLE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/feed_status.py b/google/ads/googleads/v12/enums/types/feed_status.py new file mode 100644 index 000000000..5796251d4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/feed_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FeedStatusEnum",}, +) + + +class FeedStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a feed. + """ + + class FeedStatus(proto.Enum): + r"""Possible statuses of a feed.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/flight_placeholder_field.py b/google/ads/googleads/v12/enums/types/flight_placeholder_field.py new file mode 100644 index 000000000..050968732 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/flight_placeholder_field.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FlightPlaceholderFieldEnum",}, +) + + +class FlightPlaceholderFieldEnum(proto.Message): + r"""Values for Flight placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class FlightPlaceholderField(proto.Enum): + r"""Possible values for Flight placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DESTINATION_ID = 2 + ORIGIN_ID = 3 + FLIGHT_DESCRIPTION = 4 + ORIGIN_NAME = 5 + DESTINATION_NAME = 6 + FLIGHT_PRICE = 7 + FORMATTED_PRICE = 8 + FLIGHT_SALE_PRICE = 9 + FORMATTED_SALE_PRICE = 10 + IMAGE_URL = 11 + FINAL_URLS = 12 + FINAL_MOBILE_URLS = 13 + TRACKING_URL = 14 + ANDROID_APP_LINK = 15 + SIMILAR_DESTINATION_IDS = 16 + IOS_APP_LINK = 17 + IOS_APP_STORE_ID = 18 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/frequency_cap_event_type.py b/google/ads/googleads/v12/enums/types/frequency_cap_event_type.py new file mode 100644 index 000000000..4d8ba1a7f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/frequency_cap_event_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FrequencyCapEventTypeEnum",}, +) + + +class FrequencyCapEventTypeEnum(proto.Message): + r"""Container for enum describing the type of event that the cap + applies to. + + """ + + class FrequencyCapEventType(proto.Enum): + r"""The type of event that the cap applies to (for example, + impression). + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + IMPRESSION = 2 + VIDEO_VIEW = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/frequency_cap_level.py b/google/ads/googleads/v12/enums/types/frequency_cap_level.py new file mode 100644 index 000000000..c3d82397a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/frequency_cap_level.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FrequencyCapLevelEnum",}, +) + + +class FrequencyCapLevelEnum(proto.Message): + r"""Container for enum describing the level on which the cap is + to be applied. + + """ + + class FrequencyCapLevel(proto.Enum): + r"""The level on which the cap is to be applied (e.g ad group ad, + ad group). Cap is applied to all the resources of this level. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP_AD = 2 + AD_GROUP = 3 + CAMPAIGN = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/frequency_cap_time_unit.py b/google/ads/googleads/v12/enums/types/frequency_cap_time_unit.py new file mode 100644 index 000000000..2708c703f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/frequency_cap_time_unit.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"FrequencyCapTimeUnitEnum",}, +) + + +class FrequencyCapTimeUnitEnum(proto.Message): + r"""Container for enum describing the unit of time the cap is + defined at. + + """ + + class FrequencyCapTimeUnit(proto.Enum): + r"""Unit of time the cap is defined at (for example, day, week).""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DAY = 2 + WEEK = 3 + MONTH = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/gender_type.py b/google/ads/googleads/v12/enums/types/gender_type.py new file mode 100644 index 000000000..5081cf453 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/gender_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GenderTypeEnum",}, +) + + +class GenderTypeEnum(proto.Message): + r"""Container for enum describing the type of demographic + genders. + + """ + + class GenderType(proto.Enum): + r"""The type of demographic genders (for example, female).""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MALE = 10 + FEMALE = 11 + UNDETERMINED = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/geo_target_constant_status.py b/google/ads/googleads/v12/enums/types/geo_target_constant_status.py new file mode 100644 index 000000000..aee1cd3c0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/geo_target_constant_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GeoTargetConstantStatusEnum",}, +) + + +class GeoTargetConstantStatusEnum(proto.Message): + r"""Container for describing the status of a geo target constant. + """ + + class GeoTargetConstantStatus(proto.Enum): + r"""The possible statuses of a geo target constant.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVAL_PLANNED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/geo_targeting_restriction.py b/google/ads/googleads/v12/enums/types/geo_targeting_restriction.py new file mode 100644 index 000000000..539cdd985 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/geo_targeting_restriction.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GeoTargetingRestrictionEnum",}, +) + + +class GeoTargetingRestrictionEnum(proto.Message): + r"""Message describing feed item geo targeting restriction. + """ + + class GeoTargetingRestriction(proto.Enum): + r"""A restriction used to determine if the request context's + geo should be matched. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + LOCATION_OF_PRESENCE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/geo_targeting_type.py b/google/ads/googleads/v12/enums/types/geo_targeting_type.py new file mode 100644 index 000000000..8b4008b35 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/geo_targeting_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GeoTargetingTypeEnum",}, +) + + +class GeoTargetingTypeEnum(proto.Message): + r"""Container for enum describing possible geo targeting types. + """ + + class GeoTargetingType(proto.Enum): + r"""The possible geo targeting types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AREA_OF_INTEREST = 2 + LOCATION_OF_PRESENCE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/goal_config_level.py b/google/ads/googleads/v12/enums/types/goal_config_level.py new file mode 100644 index 000000000..93694cbc4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/goal_config_level.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GoalConfigLevelEnum",}, +) + + +class GoalConfigLevelEnum(proto.Message): + r"""Container for enum describing possible goal config levels. + """ + + class GoalConfigLevel(proto.Enum): + r"""The possible goal config levels. Campaigns automatically + inherit the effective conversion account's customer goals unless + they have been configured with their own set of campaign goals. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER = 2 + CAMPAIGN = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/google_ads_field_category.py b/google/ads/googleads/v12/enums/types/google_ads_field_category.py new file mode 100644 index 000000000..c38c67c0b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/google_ads_field_category.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GoogleAdsFieldCategoryEnum",}, +) + + +class GoogleAdsFieldCategoryEnum(proto.Message): + r"""Container for enum that determines if the described artifact + is a resource or a field, and if it is a field, when it segments + search queries. + + """ + + class GoogleAdsFieldCategory(proto.Enum): + r"""The category of the artifact.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + RESOURCE = 2 + ATTRIBUTE = 3 + SEGMENT = 5 + METRIC = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/google_ads_field_data_type.py b/google/ads/googleads/v12/enums/types/google_ads_field_data_type.py new file mode 100644 index 000000000..1e6e912e6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/google_ads_field_data_type.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GoogleAdsFieldDataTypeEnum",}, +) + + +class GoogleAdsFieldDataTypeEnum(proto.Message): + r"""Container holding the various data types. + """ + + class GoogleAdsFieldDataType(proto.Enum): + r"""These are the various types a GoogleAdsService artifact may + take on. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + BOOLEAN = 2 + DATE = 3 + DOUBLE = 4 + ENUM = 5 + FLOAT = 6 + INT32 = 7 + INT64 = 8 + MESSAGE = 9 + RESOURCE_NAME = 10 + STRING = 11 + UINT64 = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/google_voice_call_status.py b/google/ads/googleads/v12/enums/types/google_voice_call_status.py new file mode 100644 index 000000000..359469506 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/google_voice_call_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"GoogleVoiceCallStatusEnum",}, +) + + +class GoogleVoiceCallStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a google + voice call. + + """ + + class GoogleVoiceCallStatus(proto.Enum): + r"""Possible statuses of a google voice call.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MISSED = 2 + RECEIVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/hotel_date_selection_type.py b/google/ads/googleads/v12/enums/types/hotel_date_selection_type.py new file mode 100644 index 000000000..60ee6a8e6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/hotel_date_selection_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"HotelDateSelectionTypeEnum",}, +) + + +class HotelDateSelectionTypeEnum(proto.Message): + r"""Container for enum describing possible hotel date selection + types + + """ + + class HotelDateSelectionType(proto.Enum): + r"""Enum describing possible hotel date selection types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DEFAULT_SELECTION = 50 + USER_SELECTED = 51 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/hotel_placeholder_field.py b/google/ads/googleads/v12/enums/types/hotel_placeholder_field.py new file mode 100644 index 000000000..1346dcab9 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/hotel_placeholder_field.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"HotelPlaceholderFieldEnum",}, +) + + +class HotelPlaceholderFieldEnum(proto.Message): + r"""Values for Hotel placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class HotelPlaceholderField(proto.Enum): + r"""Possible values for Hotel placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PROPERTY_ID = 2 + PROPERTY_NAME = 3 + DESTINATION_NAME = 4 + DESCRIPTION = 5 + ADDRESS = 6 + PRICE = 7 + FORMATTED_PRICE = 8 + SALE_PRICE = 9 + FORMATTED_SALE_PRICE = 10 + IMAGE_URL = 11 + CATEGORY = 12 + STAR_RATING = 13 + CONTEXTUAL_KEYWORDS = 14 + FINAL_URLS = 15 + FINAL_MOBILE_URLS = 16 + TRACKING_URL = 17 + ANDROID_APP_LINK = 18 + SIMILAR_PROPERTY_IDS = 19 + IOS_APP_LINK = 20 + IOS_APP_STORE_ID = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/hotel_price_bucket.py b/google/ads/googleads/v12/enums/types/hotel_price_bucket.py new file mode 100644 index 000000000..8306d47c0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/hotel_price_bucket.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"HotelPriceBucketEnum",}, +) + + +class HotelPriceBucketEnum(proto.Message): + r"""Container for enum describing hotel price bucket for a hotel + itinerary. + + """ + + class HotelPriceBucket(proto.Enum): + r"""Enum describing possible hotel price buckets.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LOWEST_UNIQUE = 2 + LOWEST_TIED = 3 + NOT_LOWEST = 4 + ONLY_PARTNER_SHOWN = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/hotel_rate_type.py b/google/ads/googleads/v12/enums/types/hotel_rate_type.py new file mode 100644 index 000000000..e8d5b6c77 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/hotel_rate_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"HotelRateTypeEnum",}, +) + + +class HotelRateTypeEnum(proto.Message): + r"""Container for enum describing possible hotel rate types. + """ + + class HotelRateType(proto.Enum): + r"""Enum describing possible hotel rate types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNAVAILABLE = 2 + PUBLIC_RATE = 3 + QUALIFIED_RATE = 4 + PRIVATE_RATE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/hotel_reconciliation_status.py b/google/ads/googleads/v12/enums/types/hotel_reconciliation_status.py new file mode 100644 index 000000000..e57a9a1a8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/hotel_reconciliation_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"HotelReconciliationStatusEnum",}, +) + + +class HotelReconciliationStatusEnum(proto.Message): + r"""Container for HotelReconciliationStatus. + """ + + class HotelReconciliationStatus(proto.Enum): + r"""Status of the hotel booking reconciliation.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + RESERVATION_ENABLED = 2 + RECONCILIATION_NEEDED = 3 + RECONCILED = 4 + CANCELED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/image_placeholder_field.py b/google/ads/googleads/v12/enums/types/image_placeholder_field.py new file mode 100644 index 000000000..047ee1443 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/image_placeholder_field.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ImagePlaceholderFieldEnum",}, +) + + +class ImagePlaceholderFieldEnum(proto.Message): + r"""Values for Advertiser Provided Image placeholder fields. + """ + + class ImagePlaceholderField(proto.Enum): + r"""Possible values for Advertiser Provided Image placeholder + fields. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ASSET_ID = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/income_range_type.py b/google/ads/googleads/v12/enums/types/income_range_type.py new file mode 100644 index 000000000..f14e0603c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/income_range_type.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"IncomeRangeTypeEnum",}, +) + + +class IncomeRangeTypeEnum(proto.Message): + r"""Container for enum describing the type of demographic income + ranges. + + """ + + class IncomeRangeType(proto.Enum): + r"""The type of demographic income ranges (for example, between + 0% to 50%). + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INCOME_RANGE_0_50 = 510001 + INCOME_RANGE_50_60 = 510002 + INCOME_RANGE_60_70 = 510003 + INCOME_RANGE_70_80 = 510004 + INCOME_RANGE_80_90 = 510005 + INCOME_RANGE_90_UP = 510006 + INCOME_RANGE_UNDETERMINED = 510000 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/interaction_event_type.py b/google/ads/googleads/v12/enums/types/interaction_event_type.py new file mode 100644 index 000000000..0c707d14c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/interaction_event_type.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"InteractionEventTypeEnum",}, +) + + +class InteractionEventTypeEnum(proto.Message): + r"""Container for enum describing types of payable and free + interactions. + + """ + + class InteractionEventType(proto.Enum): + r"""Enum describing possible types of payable and free + interactions. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CLICK = 2 + ENGAGEMENT = 3 + VIDEO_VIEW = 4 + NONE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/interaction_type.py b/google/ads/googleads/v12/enums/types/interaction_type.py new file mode 100644 index 000000000..97cb7aba1 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/interaction_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"InteractionTypeEnum",}, +) + + +class InteractionTypeEnum(proto.Message): + r"""Container for enum describing possible interaction types. + """ + + class InteractionType(proto.Enum): + r"""Enum describing possible interaction types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CALLS = 8000 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/invoice_type.py b/google/ads/googleads/v12/enums/types/invoice_type.py new file mode 100644 index 000000000..aa38f99c0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/invoice_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"InvoiceTypeEnum",}, +) + + +class InvoiceTypeEnum(proto.Message): + r"""Container for enum describing the type of invoices. + """ + + class InvoiceType(proto.Enum): + r"""The possible type of invoices.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CREDIT_MEMO = 2 + INVOICE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/job_placeholder_field.py b/google/ads/googleads/v12/enums/types/job_placeholder_field.py new file mode 100644 index 000000000..4acf98e53 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/job_placeholder_field.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"JobPlaceholderFieldEnum",}, +) + + +class JobPlaceholderFieldEnum(proto.Message): + r"""Values for Job placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class JobPlaceholderField(proto.Enum): + r"""Possible values for Job placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + JOB_ID = 2 + LOCATION_ID = 3 + TITLE = 4 + SUBTITLE = 5 + DESCRIPTION = 6 + IMAGE_URL = 7 + CATEGORY = 8 + CONTEXTUAL_KEYWORDS = 9 + ADDRESS = 10 + SALARY = 11 + FINAL_URLS = 12 + FINAL_MOBILE_URLS = 14 + TRACKING_URL = 15 + ANDROID_APP_LINK = 16 + SIMILAR_JOB_IDS = 17 + IOS_APP_LINK = 18 + IOS_APP_STORE_ID = 19 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_match_type.py b/google/ads/googleads/v12/enums/types/keyword_match_type.py new file mode 100644 index 000000000..a9937c8f3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_match_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordMatchTypeEnum",}, +) + + +class KeywordMatchTypeEnum(proto.Message): + r"""Message describing Keyword match types. + """ + + class KeywordMatchType(proto.Enum): + r"""Possible Keyword match types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXACT = 2 + PHRASE = 3 + BROAD = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_aggregate_metric_type.py b/google/ads/googleads/v12/enums/types/keyword_plan_aggregate_metric_type.py new file mode 100644 index 000000000..4f735faaf --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_aggregate_metric_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanAggregateMetricTypeEnum",}, +) + + +class KeywordPlanAggregateMetricTypeEnum(proto.Message): + r"""The enumeration of keyword plan aggregate metric types. + """ + + class KeywordPlanAggregateMetricType(proto.Enum): + r"""Aggregate fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DEVICE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_competition_level.py b/google/ads/googleads/v12/enums/types/keyword_plan_competition_level.py new file mode 100644 index 000000000..7a1a2b3f3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_competition_level.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanCompetitionLevelEnum",}, +) + + +class KeywordPlanCompetitionLevelEnum(proto.Message): + r"""Container for enumeration of keyword competition levels. The + competition level indicates how competitive ad placement is for + a keyword and is determined by the number of advertisers bidding + on that keyword relative to all keywords across Google. The + competition level can depend on the location and Search Network + targeting options you've selected. + + """ + + class KeywordPlanCompetitionLevel(proto.Enum): + r"""Competition level of a keyword.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LOW = 2 + MEDIUM = 3 + HIGH = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_concept_group_type.py b/google/ads/googleads/v12/enums/types/keyword_plan_concept_group_type.py new file mode 100644 index 000000000..08396391e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_concept_group_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanConceptGroupTypeEnum",}, +) + + +class KeywordPlanConceptGroupTypeEnum(proto.Message): + r"""Container for enumeration of keyword plan concept group + types. + + """ + + class KeywordPlanConceptGroupType(proto.Enum): + r"""Enumerates keyword plan concept group types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BRAND = 2 + OTHER_BRANDS = 3 + NON_BRAND = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_forecast_interval.py b/google/ads/googleads/v12/enums/types/keyword_plan_forecast_interval.py new file mode 100644 index 000000000..e95be0442 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_forecast_interval.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanForecastIntervalEnum",}, +) + + +class KeywordPlanForecastIntervalEnum(proto.Message): + r"""Container for enumeration of forecast intervals. + """ + + class KeywordPlanForecastInterval(proto.Enum): + r"""Forecast intervals.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NEXT_WEEK = 3 + NEXT_MONTH = 4 + NEXT_QUARTER = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_keyword_annotation.py b/google/ads/googleads/v12/enums/types/keyword_plan_keyword_annotation.py new file mode 100644 index 000000000..3fc92613c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_keyword_annotation.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanKeywordAnnotationEnum",}, +) + + +class KeywordPlanKeywordAnnotationEnum(proto.Message): + r"""Container for enumeration of keyword plan keyword + annotations. + + """ + + class KeywordPlanKeywordAnnotation(proto.Enum): + r"""Enumerates keyword plan annotations that can be requested.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + KEYWORD_CONCEPT = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/keyword_plan_network.py b/google/ads/googleads/v12/enums/types/keyword_plan_network.py new file mode 100644 index 000000000..86655fdf3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/keyword_plan_network.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanNetworkEnum",}, +) + + +class KeywordPlanNetworkEnum(proto.Message): + r"""Container for enumeration of keyword plan forecastable + network types. + + """ + + class KeywordPlanNetwork(proto.Enum): + r"""Enumerates keyword plan forecastable network types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + GOOGLE_SEARCH = 2 + GOOGLE_SEARCH_AND_PARTNERS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/label_status.py b/google/ads/googleads/v12/enums/types/label_status.py new file mode 100644 index 000000000..6348110d3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/label_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LabelStatusEnum",}, +) + + +class LabelStatusEnum(proto.Message): + r"""Container for enum describing possible status of a label. + """ + + class LabelStatus(proto.Enum): + r"""Possible statuses of a label.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/lead_form_call_to_action_type.py b/google/ads/googleads/v12/enums/types/lead_form_call_to_action_type.py new file mode 100644 index 000000000..cd768f9a7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/lead_form_call_to_action_type.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LeadFormCallToActionTypeEnum",}, +) + + +class LeadFormCallToActionTypeEnum(proto.Message): + r"""Describes the type of call-to-action phrases in a lead form. + """ + + class LeadFormCallToActionType(proto.Enum): + r"""Enum describing the type of call-to-action phrases in a lead + form. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + LEARN_MORE = 2 + GET_QUOTE = 3 + APPLY_NOW = 4 + SIGN_UP = 5 + CONTACT_US = 6 + SUBSCRIBE = 7 + DOWNLOAD = 8 + BOOK_NOW = 9 + GET_OFFER = 10 + REGISTER = 11 + GET_INFO = 12 + REQUEST_DEMO = 13 + JOIN_NOW = 14 + GET_STARTED = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/lead_form_desired_intent.py b/google/ads/googleads/v12/enums/types/lead_form_desired_intent.py new file mode 100644 index 000000000..5fedc8f68 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/lead_form_desired_intent.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LeadFormDesiredIntentEnum",}, +) + + +class LeadFormDesiredIntentEnum(proto.Message): + r"""Describes the chosen level of intent of generated leads. + """ + + class LeadFormDesiredIntent(proto.Enum): + r"""Enum describing the chosen level of intent of generated + leads. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + LOW_INTENT = 2 + HIGH_INTENT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/lead_form_field_user_input_type.py b/google/ads/googleads/v12/enums/types/lead_form_field_user_input_type.py new file mode 100644 index 000000000..69cfa02af --- /dev/null +++ b/google/ads/googleads/v12/enums/types/lead_form_field_user_input_type.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LeadFormFieldUserInputTypeEnum",}, +) + + +class LeadFormFieldUserInputTypeEnum(proto.Message): + r"""Describes the input type of a lead form field. + """ + + class LeadFormFieldUserInputType(proto.Enum): + r"""Enum describing the input type of a lead form field.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FULL_NAME = 2 + EMAIL = 3 + PHONE_NUMBER = 4 + POSTAL_CODE = 5 + STREET_ADDRESS = 8 + CITY = 9 + REGION = 10 + COUNTRY = 11 + WORK_EMAIL = 12 + COMPANY_NAME = 13 + WORK_PHONE = 14 + JOB_TITLE = 15 + GOVERNMENT_ISSUED_ID_CPF_BR = 16 + GOVERNMENT_ISSUED_ID_DNI_AR = 17 + GOVERNMENT_ISSUED_ID_DNI_PE = 18 + GOVERNMENT_ISSUED_ID_RUT_CL = 19 + GOVERNMENT_ISSUED_ID_CC_CO = 20 + GOVERNMENT_ISSUED_ID_CI_EC = 21 + GOVERNMENT_ISSUED_ID_RFC_MX = 22 + FIRST_NAME = 23 + LAST_NAME = 24 + VEHICLE_MODEL = 1001 + VEHICLE_TYPE = 1002 + PREFERRED_DEALERSHIP = 1003 + VEHICLE_PURCHASE_TIMELINE = 1004 + VEHICLE_OWNERSHIP = 1005 + VEHICLE_PAYMENT_TYPE = 1009 + VEHICLE_CONDITION = 1010 + COMPANY_SIZE = 1006 + ANNUAL_SALES = 1007 + YEARS_IN_BUSINESS = 1008 + JOB_DEPARTMENT = 1011 + JOB_ROLE = 1012 + OVER_18_AGE = 1078 + OVER_19_AGE = 1079 + OVER_20_AGE = 1080 + OVER_21_AGE = 1081 + OVER_22_AGE = 1082 + OVER_23_AGE = 1083 + OVER_24_AGE = 1084 + OVER_25_AGE = 1085 + OVER_26_AGE = 1086 + OVER_27_AGE = 1087 + OVER_28_AGE = 1088 + OVER_29_AGE = 1089 + OVER_30_AGE = 1090 + OVER_31_AGE = 1091 + OVER_32_AGE = 1092 + OVER_33_AGE = 1093 + OVER_34_AGE = 1094 + OVER_35_AGE = 1095 + OVER_36_AGE = 1096 + OVER_37_AGE = 1097 + OVER_38_AGE = 1098 + OVER_39_AGE = 1099 + OVER_40_AGE = 1100 + OVER_41_AGE = 1101 + OVER_42_AGE = 1102 + OVER_43_AGE = 1103 + OVER_44_AGE = 1104 + OVER_45_AGE = 1105 + OVER_46_AGE = 1106 + OVER_47_AGE = 1107 + OVER_48_AGE = 1108 + OVER_49_AGE = 1109 + OVER_50_AGE = 1110 + OVER_51_AGE = 1111 + OVER_52_AGE = 1112 + OVER_53_AGE = 1113 + OVER_54_AGE = 1114 + OVER_55_AGE = 1115 + OVER_56_AGE = 1116 + OVER_57_AGE = 1117 + OVER_58_AGE = 1118 + OVER_59_AGE = 1119 + OVER_60_AGE = 1120 + OVER_61_AGE = 1121 + OVER_62_AGE = 1122 + OVER_63_AGE = 1123 + OVER_64_AGE = 1124 + OVER_65_AGE = 1125 + EDUCATION_PROGRAM = 1013 + EDUCATION_COURSE = 1014 + PRODUCT = 1016 + SERVICE = 1017 + OFFER = 1018 + CATEGORY = 1019 + PREFERRED_CONTACT_METHOD = 1020 + PREFERRED_LOCATION = 1021 + PREFERRED_CONTACT_TIME = 1022 + PURCHASE_TIMELINE = 1023 + YEARS_OF_EXPERIENCE = 1048 + JOB_INDUSTRY = 1049 + LEVEL_OF_EDUCATION = 1050 + PROPERTY_TYPE = 1024 + REALTOR_HELP_GOAL = 1025 + PROPERTY_COMMUNITY = 1026 + PRICE_RANGE = 1027 + NUMBER_OF_BEDROOMS = 1028 + FURNISHED_PROPERTY = 1029 + PETS_ALLOWED_PROPERTY = 1030 + NEXT_PLANNED_PURCHASE = 1031 + EVENT_SIGNUP_INTEREST = 1033 + PREFERRED_SHOPPING_PLACES = 1034 + FAVORITE_BRAND = 1035 + TRANSPORTATION_COMMERCIAL_LICENSE_TYPE = 1036 + EVENT_BOOKING_INTEREST = 1038 + DESTINATION_COUNTRY = 1039 + DESTINATION_CITY = 1040 + DEPARTURE_COUNTRY = 1041 + DEPARTURE_CITY = 1042 + DEPARTURE_DATE = 1043 + RETURN_DATE = 1044 + NUMBER_OF_TRAVELERS = 1045 + TRAVEL_BUDGET = 1046 + TRAVEL_ACCOMMODATION = 1047 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/lead_form_post_submit_call_to_action_type.py b/google/ads/googleads/v12/enums/types/lead_form_post_submit_call_to_action_type.py new file mode 100644 index 000000000..85c0c9332 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/lead_form_post_submit_call_to_action_type.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LeadFormPostSubmitCallToActionTypeEnum",}, +) + + +class LeadFormPostSubmitCallToActionTypeEnum(proto.Message): + r"""Describes the type of post-submit call-to-action phrases for + a lead form. + + """ + + class LeadFormPostSubmitCallToActionType(proto.Enum): + r"""Enum describing the type of post-submit call-to-action + phrases for a lead form. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + VISIT_SITE = 2 + DOWNLOAD = 3 + LEARN_MORE = 4 + SHOP_NOW = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/legacy_app_install_ad_app_store.py b/google/ads/googleads/v12/enums/types/legacy_app_install_ad_app_store.py new file mode 100644 index 000000000..8292f9d95 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/legacy_app_install_ad_app_store.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LegacyAppInstallAdAppStoreEnum",}, +) + + +class LegacyAppInstallAdAppStoreEnum(proto.Message): + r"""Container for enum describing app store type in a legacy app + install ad. + + """ + + class LegacyAppInstallAdAppStore(proto.Enum): + r"""App store type in a legacy app install ad.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APPLE_APP_STORE = 2 + GOOGLE_PLAY = 3 + WINDOWS_STORE = 4 + WINDOWS_PHONE_STORE = 5 + CN_APP_STORE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/linked_account_type.py b/google/ads/googleads/v12/enums/types/linked_account_type.py new file mode 100644 index 000000000..302e3d4fe --- /dev/null +++ b/google/ads/googleads/v12/enums/types/linked_account_type.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LinkedAccountTypeEnum",}, +) + + +class LinkedAccountTypeEnum(proto.Message): + r"""Container for enum describing different types of Linked + accounts. + + """ + + class LinkedAccountType(proto.Enum): + r"""Describes the possible link types between a Google Ads + customer and another account. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + THIRD_PARTY_APP_ANALYTICS = 2 + DATA_PARTNER = 3 + GOOGLE_ADS = 4 + HOTEL_CENTER = 5 + ADVERTISING_PARTNER = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_bidding_category_level.py b/google/ads/googleads/v12/enums/types/listing_group_filter_bidding_category_level.py new file mode 100644 index 000000000..6b1896d1c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_bidding_category_level.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterBiddingCategoryLevelEnum",}, +) + + +class ListingGroupFilterBiddingCategoryLevelEnum(proto.Message): + r"""Container for enum describing the levels of bidding category + used in ListingGroupFilterDimension. + + """ + + class ListingGroupFilterBiddingCategoryLevel(proto.Enum): + r"""The level of the listing group filter bidding category.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LEVEL1 = 2 + LEVEL2 = 3 + LEVEL3 = 4 + LEVEL4 = 5 + LEVEL5 = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_custom_attribute_index.py b/google/ads/googleads/v12/enums/types/listing_group_filter_custom_attribute_index.py new file mode 100644 index 000000000..1a5452bd7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_custom_attribute_index.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterCustomAttributeIndexEnum",}, +) + + +class ListingGroupFilterCustomAttributeIndexEnum(proto.Message): + r"""Container for enum describing the indexes of custom attribute + used in ListingGroupFilterDimension. + + """ + + class ListingGroupFilterCustomAttributeIndex(proto.Enum): + r"""The index of customer attributes.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INDEX0 = 2 + INDEX1 = 3 + INDEX2 = 4 + INDEX3 = 5 + INDEX4 = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_product_channel.py b/google/ads/googleads/v12/enums/types/listing_group_filter_product_channel.py new file mode 100644 index 000000000..6abc4f431 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_product_channel.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterProductChannelEnum",}, +) + + +class ListingGroupFilterProductChannelEnum(proto.Message): + r"""Locality of a product offer. + """ + + class ListingGroupFilterProductChannel(proto.Enum): + r"""Enum describing the locality of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ONLINE = 2 + LOCAL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_product_condition.py b/google/ads/googleads/v12/enums/types/listing_group_filter_product_condition.py new file mode 100644 index 000000000..37676a052 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_product_condition.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterProductConditionEnum",}, +) + + +class ListingGroupFilterProductConditionEnum(proto.Message): + r"""Condition of a product offer. + """ + + class ListingGroupFilterProductCondition(proto.Enum): + r"""Enum describing the condition of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NEW = 2 + REFURBISHED = 3 + USED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_product_type_level.py b/google/ads/googleads/v12/enums/types/listing_group_filter_product_type_level.py new file mode 100644 index 000000000..e6bff861d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_product_type_level.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterProductTypeLevelEnum",}, +) + + +class ListingGroupFilterProductTypeLevelEnum(proto.Message): + r"""Level of the type of a product offer. + """ + + class ListingGroupFilterProductTypeLevel(proto.Enum): + r"""Enum describing the level of the type of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LEVEL1 = 2 + LEVEL2 = 3 + LEVEL3 = 4 + LEVEL4 = 5 + LEVEL5 = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_type_enum.py b/google/ads/googleads/v12/enums/types/listing_group_filter_type_enum.py new file mode 100644 index 000000000..9eff2c95f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_type_enum.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterTypeEnum",}, +) + + +class ListingGroupFilterTypeEnum(proto.Message): + r"""Container for enum describing the type of the listing group + filter node. + + """ + + class ListingGroupFilterType(proto.Enum): + r"""The type of the listing group filter.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SUBDIVISION = 2 + UNIT_INCLUDED = 3 + UNIT_EXCLUDED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_filter_vertical.py b/google/ads/googleads/v12/enums/types/listing_group_filter_vertical.py new file mode 100644 index 000000000..4cf677ccb --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_filter_vertical.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupFilterVerticalEnum",}, +) + + +class ListingGroupFilterVerticalEnum(proto.Message): + r"""Container for enum describing the type of the vertical a + listing group filter tree represents. + + """ + + class ListingGroupFilterVertical(proto.Enum): + r"""The type of the listing group filter vertical.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SHOPPING = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/listing_group_type.py b/google/ads/googleads/v12/enums/types/listing_group_type.py new file mode 100644 index 000000000..1523afced --- /dev/null +++ b/google/ads/googleads/v12/enums/types/listing_group_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ListingGroupTypeEnum",}, +) + + +class ListingGroupTypeEnum(proto.Message): + r"""Container for enum describing the type of the listing group. + """ + + class ListingGroupType(proto.Enum): + r"""The type of the listing group.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SUBDIVISION = 2 + UNIT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/local_placeholder_field.py b/google/ads/googleads/v12/enums/types/local_placeholder_field.py new file mode 100644 index 000000000..56f7b48d6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/local_placeholder_field.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocalPlaceholderFieldEnum",}, +) + + +class LocalPlaceholderFieldEnum(proto.Message): + r"""Values for Local placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class LocalPlaceholderField(proto.Enum): + r"""Possible values for Local placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DEAL_ID = 2 + DEAL_NAME = 3 + SUBTITLE = 4 + DESCRIPTION = 5 + PRICE = 6 + FORMATTED_PRICE = 7 + SALE_PRICE = 8 + FORMATTED_SALE_PRICE = 9 + IMAGE_URL = 10 + ADDRESS = 11 + CATEGORY = 12 + CONTEXTUAL_KEYWORDS = 13 + FINAL_URLS = 14 + FINAL_MOBILE_URLS = 15 + TRACKING_URL = 16 + ANDROID_APP_LINK = 17 + SIMILAR_DEAL_IDS = 18 + IOS_APP_LINK = 19 + IOS_APP_STORE_ID = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_extension_targeting_criterion_field.py b/google/ads/googleads/v12/enums/types/location_extension_targeting_criterion_field.py new file mode 100644 index 000000000..ace1ab1ae --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_extension_targeting_criterion_field.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationExtensionTargetingCriterionFieldEnum",}, +) + + +class LocationExtensionTargetingCriterionFieldEnum(proto.Message): + r"""Values for Location Extension Targeting criterion fields. + """ + + class LocationExtensionTargetingCriterionField(proto.Enum): + r"""Possible values for Location Extension Targeting criterion + fields. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ADDRESS_LINE_1 = 2 + ADDRESS_LINE_2 = 3 + CITY = 4 + PROVINCE = 5 + POSTAL_CODE = 6 + COUNTRY_CODE = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_group_radius_units.py b/google/ads/googleads/v12/enums/types/location_group_radius_units.py new file mode 100644 index 000000000..b2c689d2e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_group_radius_units.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationGroupRadiusUnitsEnum",}, +) + + +class LocationGroupRadiusUnitsEnum(proto.Message): + r"""Container for enum describing unit of radius in location + group. + + """ + + class LocationGroupRadiusUnits(proto.Enum): + r"""The unit of radius distance in location group (for example, + MILES) + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + METERS = 2 + MILES = 3 + MILLI_MILES = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_ownership_type.py b/google/ads/googleads/v12/enums/types/location_ownership_type.py new file mode 100644 index 000000000..ad14b8092 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_ownership_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationOwnershipTypeEnum",}, +) + + +class LocationOwnershipTypeEnum(proto.Message): + r"""Container for enum describing possible types of a location + ownership. + + """ + + class LocationOwnershipType(proto.Enum): + r"""Possible types of a location ownership.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BUSINESS_OWNER = 2 + AFFILIATE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_placeholder_field.py b/google/ads/googleads/v12/enums/types/location_placeholder_field.py new file mode 100644 index 000000000..d91bce942 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_placeholder_field.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationPlaceholderFieldEnum",}, +) + + +class LocationPlaceholderFieldEnum(proto.Message): + r"""Values for Location placeholder fields. + """ + + class LocationPlaceholderField(proto.Enum): + r"""Possible values for Location placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BUSINESS_NAME = 2 + ADDRESS_LINE_1 = 3 + ADDRESS_LINE_2 = 4 + CITY = 5 + PROVINCE = 6 + POSTAL_CODE = 7 + COUNTRY_CODE = 8 + PHONE_NUMBER = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_source_type.py b/google/ads/googleads/v12/enums/types/location_source_type.py new file mode 100644 index 000000000..b57981cf2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_source_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationSourceTypeEnum",}, +) + + +class LocationSourceTypeEnum(proto.Message): + r"""Used to distinguish the location source type. + """ + + class LocationSourceType(proto.Enum): + r"""The possible types of a location source.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + GOOGLE_MY_BUSINESS = 2 + AFFILIATE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/location_string_filter_type.py b/google/ads/googleads/v12/enums/types/location_string_filter_type.py new file mode 100644 index 000000000..317fa5071 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/location_string_filter_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"LocationStringFilterTypeEnum",}, +) + + +class LocationStringFilterTypeEnum(proto.Message): + r"""Container for enum describing possible types of a location + string filter. + + """ + + class LocationStringFilterType(proto.Enum): + r"""Possible types of a location string filter.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXACT = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/manager_link_status.py b/google/ads/googleads/v12/enums/types/manager_link_status.py new file mode 100644 index 000000000..94f01d96f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/manager_link_status.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ManagerLinkStatusEnum",}, +) + + +class ManagerLinkStatusEnum(proto.Message): + r"""Container for enum describing possible status of a manager + and client link. + + """ + + class ManagerLinkStatus(proto.Enum): + r"""Possible statuses of a link.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACTIVE = 2 + INACTIVE = 3 + PENDING = 4 + REFUSED = 5 + CANCELED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/matching_function_context_type.py b/google/ads/googleads/v12/enums/types/matching_function_context_type.py new file mode 100644 index 000000000..97aa662cd --- /dev/null +++ b/google/ads/googleads/v12/enums/types/matching_function_context_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MatchingFunctionContextTypeEnum",}, +) + + +class MatchingFunctionContextTypeEnum(proto.Message): + r"""Container for context types for an operand in a matching + function. + + """ + + class MatchingFunctionContextType(proto.Enum): + r"""Possible context types for an operand in a matching function.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ITEM_ID = 2 + DEVICE_NAME = 3 + FEED_ITEM_SET_ID = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/matching_function_operator.py b/google/ads/googleads/v12/enums/types/matching_function_operator.py new file mode 100644 index 000000000..2f0ca8189 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/matching_function_operator.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MatchingFunctionOperatorEnum",}, +) + + +class MatchingFunctionOperatorEnum(proto.Message): + r"""Container for enum describing matching function operator. + """ + + class MatchingFunctionOperator(proto.Enum): + r"""Possible operators in a matching function.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + IN = 2 + IDENTITY = 3 + EQUALS = 4 + AND = 5 + CONTAINS_ANY = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/media_type.py b/google/ads/googleads/v12/enums/types/media_type.py new file mode 100644 index 000000000..143b5e8e0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/media_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MediaTypeEnum",}, +) + + +class MediaTypeEnum(proto.Message): + r"""Container for enum describing the types of media. + """ + + class MediaType(proto.Enum): + r"""The type of media.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + IMAGE = 2 + ICON = 3 + MEDIA_BUNDLE = 4 + AUDIO = 5 + VIDEO = 6 + DYNAMIC_IMAGE = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/merchant_center_link_status.py b/google/ads/googleads/v12/enums/types/merchant_center_link_status.py new file mode 100644 index 000000000..8324d6b81 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/merchant_center_link_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MerchantCenterLinkStatusEnum",}, +) + + +class MerchantCenterLinkStatusEnum(proto.Message): + r"""Container for enum describing possible statuses of a Google + Merchant Center link. + + """ + + class MerchantCenterLinkStatus(proto.Enum): + r"""Describes the possible statuses for a link between a Google + Ads customer and a Google Merchant Center account. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + PENDING = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/message_placeholder_field.py b/google/ads/googleads/v12/enums/types/message_placeholder_field.py new file mode 100644 index 000000000..7a2295501 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/message_placeholder_field.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MessagePlaceholderFieldEnum",}, +) + + +class MessagePlaceholderFieldEnum(proto.Message): + r"""Values for Message placeholder fields. + """ + + class MessagePlaceholderField(proto.Enum): + r"""Possible values for Message placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BUSINESS_NAME = 2 + COUNTRY_CODE = 3 + PHONE_NUMBER = 4 + MESSAGE_EXTENSION_TEXT = 5 + MESSAGE_TEXT = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/mime_type.py b/google/ads/googleads/v12/enums/types/mime_type.py new file mode 100644 index 000000000..4788668be --- /dev/null +++ b/google/ads/googleads/v12/enums/types/mime_type.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MimeTypeEnum",}, +) + + +class MimeTypeEnum(proto.Message): + r"""Container for enum describing the mime types. + """ + + class MimeType(proto.Enum): + r"""The mime type""" + UNSPECIFIED = 0 + UNKNOWN = 1 + IMAGE_JPEG = 2 + IMAGE_GIF = 3 + IMAGE_PNG = 4 + FLASH = 5 + TEXT_HTML = 6 + PDF = 7 + MSWORD = 8 + MSEXCEL = 9 + RTF = 10 + AUDIO_WAV = 11 + AUDIO_MP3 = 12 + HTML5_AD_ZIP = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/minute_of_hour.py b/google/ads/googleads/v12/enums/types/minute_of_hour.py new file mode 100644 index 000000000..1e69721b2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/minute_of_hour.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MinuteOfHourEnum",}, +) + + +class MinuteOfHourEnum(proto.Message): + r"""Container for enumeration of quarter-hours. + """ + + class MinuteOfHour(proto.Enum): + r"""Enumerates of quarter-hours. For example, "FIFTEEN".""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ZERO = 2 + FIFTEEN = 3 + THIRTY = 4 + FORTY_FIVE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/mobile_app_vendor.py b/google/ads/googleads/v12/enums/types/mobile_app_vendor.py new file mode 100644 index 000000000..43850c421 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/mobile_app_vendor.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MobileAppVendorEnum",}, +) + + +class MobileAppVendorEnum(proto.Message): + r"""Container for enum describing different types of mobile app + vendors. + + """ + + class MobileAppVendor(proto.Enum): + r"""The type of mobile app vendor""" + UNSPECIFIED = 0 + UNKNOWN = 1 + APPLE_APP_STORE = 2 + GOOGLE_APP_STORE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/mobile_device_type.py b/google/ads/googleads/v12/enums/types/mobile_device_type.py new file mode 100644 index 000000000..c51d0e77b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/mobile_device_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MobileDeviceTypeEnum",}, +) + + +class MobileDeviceTypeEnum(proto.Message): + r"""Container for enum describing the types of mobile device. + """ + + class MobileDeviceType(proto.Enum): + r"""The type of mobile device.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MOBILE = 2 + TABLET = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/month_of_year.py b/google/ads/googleads/v12/enums/types/month_of_year.py new file mode 100644 index 000000000..01d9a314e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/month_of_year.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"MonthOfYearEnum",}, +) + + +class MonthOfYearEnum(proto.Message): + r"""Container for enumeration of months of the year, for example, + "January". + + """ + + class MonthOfYear(proto.Enum): + r"""Enumerates months of the year, for example, "January".""" + UNSPECIFIED = 0 + UNKNOWN = 1 + JANUARY = 2 + FEBRUARY = 3 + MARCH = 4 + APRIL = 5 + MAY = 6 + JUNE = 7 + JULY = 8 + AUGUST = 9 + SEPTEMBER = 10 + OCTOBER = 11 + NOVEMBER = 12 + DECEMBER = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/negative_geo_target_type.py b/google/ads/googleads/v12/enums/types/negative_geo_target_type.py new file mode 100644 index 000000000..e3aa0d557 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/negative_geo_target_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"NegativeGeoTargetTypeEnum",}, +) + + +class NegativeGeoTargetTypeEnum(proto.Message): + r"""Container for enum describing possible negative geo target + types. + + """ + + class NegativeGeoTargetType(proto.Enum): + r"""The possible negative geo target types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PRESENCE_OR_INTEREST = 4 + PRESENCE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/offline_user_data_job_failure_reason.py b/google/ads/googleads/v12/enums/types/offline_user_data_job_failure_reason.py new file mode 100644 index 000000000..10aaec83e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/offline_user_data_job_failure_reason.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJobFailureReasonEnum",}, +) + + +class OfflineUserDataJobFailureReasonEnum(proto.Message): + r"""Container for enum describing reasons why an offline user + data job failed to be processed. + + """ + + class OfflineUserDataJobFailureReason(proto.Enum): + r"""The failure reason of an offline user data job.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INSUFFICIENT_MATCHED_TRANSACTIONS = 2 + INSUFFICIENT_TRANSACTIONS = 3 + HIGH_AVERAGE_TRANSACTION_VALUE = 4 + LOW_AVERAGE_TRANSACTION_VALUE = 5 + NEWLY_OBSERVED_CURRENCY_CODE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/offline_user_data_job_match_rate_range.py b/google/ads/googleads/v12/enums/types/offline_user_data_job_match_rate_range.py new file mode 100644 index 000000000..e5554a580 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/offline_user_data_job_match_rate_range.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJobMatchRateRangeEnum",}, +) + + +class OfflineUserDataJobMatchRateRangeEnum(proto.Message): + r"""Container for enum describing reasons match rate ranges for a + customer match list upload. + + """ + + class OfflineUserDataJobMatchRateRange(proto.Enum): + r"""The match rate range of an offline user data job.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MATCH_RANGE_LESS_THAN_20 = 2 + MATCH_RANGE_20_TO_30 = 3 + MATCH_RANGE_31_TO_40 = 4 + MATCH_RANGE_41_TO_50 = 5 + MATCH_RANGE_51_TO_60 = 6 + MATCH_RANGE_61_TO_70 = 7 + MATCH_RANGE_71_TO_80 = 8 + MATCH_RANGE_81_TO_90 = 9 + MATCH_RANGE_91_TO_100 = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/offline_user_data_job_status.py b/google/ads/googleads/v12/enums/types/offline_user_data_job_status.py new file mode 100644 index 000000000..3649953ee --- /dev/null +++ b/google/ads/googleads/v12/enums/types/offline_user_data_job_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJobStatusEnum",}, +) + + +class OfflineUserDataJobStatusEnum(proto.Message): + r"""Container for enum describing status of an offline user data + job. + + """ + + class OfflineUserDataJobStatus(proto.Enum): + r"""The status of an offline user data job.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PENDING = 2 + RUNNING = 3 + SUCCESS = 4 + FAILED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/offline_user_data_job_type.py b/google/ads/googleads/v12/enums/types/offline_user_data_job_type.py new file mode 100644 index 000000000..96b33a8f8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/offline_user_data_job_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJobTypeEnum",}, +) + + +class OfflineUserDataJobTypeEnum(proto.Message): + r"""Container for enum describing types of an offline user data + job. + + """ + + class OfflineUserDataJobType(proto.Enum): + r"""The type of an offline user data job.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + STORE_SALES_UPLOAD_FIRST_PARTY = 2 + STORE_SALES_UPLOAD_THIRD_PARTY = 3 + CUSTOMER_MATCH_USER_LIST = 4 + CUSTOMER_MATCH_WITH_ATTRIBUTES = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/operating_system_version_operator_type.py b/google/ads/googleads/v12/enums/types/operating_system_version_operator_type.py new file mode 100644 index 000000000..f7e3c4f45 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/operating_system_version_operator_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OperatingSystemVersionOperatorTypeEnum",}, +) + + +class OperatingSystemVersionOperatorTypeEnum(proto.Message): + r"""Container for enum describing the type of OS operators. + """ + + class OperatingSystemVersionOperatorType(proto.Enum): + r"""The type of operating system version.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EQUALS_TO = 2 + GREATER_THAN_EQUALS_TO = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/optimization_goal_type.py b/google/ads/googleads/v12/enums/types/optimization_goal_type.py new file mode 100644 index 000000000..33d41dc32 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/optimization_goal_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"OptimizationGoalTypeEnum",}, +) + + +class OptimizationGoalTypeEnum(proto.Message): + r"""Container for enum describing the type of optimization goal. + """ + + class OptimizationGoalType(proto.Enum): + r"""The type of optimization goal""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CALL_CLICKS = 2 + DRIVING_DIRECTIONS = 3 + APP_PRE_REGISTRATION = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/parental_status_type.py b/google/ads/googleads/v12/enums/types/parental_status_type.py new file mode 100644 index 000000000..c303ba33a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/parental_status_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ParentalStatusTypeEnum",}, +) + + +class ParentalStatusTypeEnum(proto.Message): + r"""Container for enum describing the type of demographic + parental statuses. + + """ + + class ParentalStatusType(proto.Enum): + r"""The type of parental statuses (for example, not a parent).""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PARENT = 300 + NOT_A_PARENT = 301 + UNDETERMINED = 302 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/payment_mode.py b/google/ads/googleads/v12/enums/types/payment_mode.py new file mode 100644 index 000000000..8c98804ef --- /dev/null +++ b/google/ads/googleads/v12/enums/types/payment_mode.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PaymentModeEnum",}, +) + + +class PaymentModeEnum(proto.Message): + r"""Container for enum describing possible payment modes. + """ + + class PaymentMode(proto.Enum): + r"""Enum describing possible payment modes.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CLICKS = 4 + CONVERSION_VALUE = 5 + CONVERSIONS = 6 + GUEST_STAY = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/performance_max_upgrade_status.py b/google/ads/googleads/v12/enums/types/performance_max_upgrade_status.py new file mode 100644 index 000000000..887d2d2d3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/performance_max_upgrade_status.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PerformanceMaxUpgradeStatusEnum",}, +) + + +class PerformanceMaxUpgradeStatusEnum(proto.Message): + r"""Performance Max Upgrade status for campaign. + """ + + class PerformanceMaxUpgradeStatus(proto.Enum): + r"""Performance Max Upgrade status enum for campaign.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UPGRADE_ELIBIGLE = 2 + UPGRADE_IN_PROGRESS = 3 + UPGRADE_COMPLETE = 4 + UPGRADE_FAILED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/placeholder_type.py b/google/ads/googleads/v12/enums/types/placeholder_type.py new file mode 100644 index 000000000..3e22e9f62 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/placeholder_type.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PlaceholderTypeEnum",}, +) + + +class PlaceholderTypeEnum(proto.Message): + r"""Container for enum describing possible placeholder types for + a feed mapping. + + """ + + class PlaceholderType(proto.Enum): + r"""Possible placeholder types for a feed mapping.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SITELINK = 2 + CALL = 3 + APP = 4 + LOCATION = 5 + AFFILIATE_LOCATION = 6 + CALLOUT = 7 + STRUCTURED_SNIPPET = 8 + MESSAGE = 9 + PRICE = 10 + PROMOTION = 11 + AD_CUSTOMIZER = 12 + DYNAMIC_EDUCATION = 13 + DYNAMIC_FLIGHT = 14 + DYNAMIC_CUSTOM = 15 + DYNAMIC_HOTEL = 16 + DYNAMIC_REAL_ESTATE = 17 + DYNAMIC_TRAVEL = 18 + DYNAMIC_LOCAL = 19 + DYNAMIC_JOB = 20 + IMAGE = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/placement_type.py b/google/ads/googleads/v12/enums/types/placement_type.py new file mode 100644 index 000000000..cc2e8c40a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/placement_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PlacementTypeEnum",}, +) + + +class PlacementTypeEnum(proto.Message): + r"""Container for enum describing possible placement types. + """ + + class PlacementType(proto.Enum): + r"""Possible placement types for a feed mapping.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + WEBSITE = 2 + MOBILE_APP_CATEGORY = 3 + MOBILE_APPLICATION = 4 + YOUTUBE_VIDEO = 5 + YOUTUBE_CHANNEL = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_approval_status.py b/google/ads/googleads/v12/enums/types/policy_approval_status.py new file mode 100644 index 000000000..85d4c11e0 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_approval_status.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyApprovalStatusEnum",}, +) + + +class PolicyApprovalStatusEnum(proto.Message): + r"""Container for enum describing possible policy approval + statuses. + + """ + + class PolicyApprovalStatus(proto.Enum): + r"""The possible policy approval statuses. When there are several + approval statuses available the most severe one will be used. The + order of severity is DISAPPROVED, AREA_OF_INTEREST_ONLY, + APPROVED_LIMITED and APPROVED. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + DISAPPROVED = 2 + APPROVED_LIMITED = 3 + APPROVED = 4 + AREA_OF_INTEREST_ONLY = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_review_status.py b/google/ads/googleads/v12/enums/types/policy_review_status.py new file mode 100644 index 000000000..b8e11d40b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_review_status.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyReviewStatusEnum",}, +) + + +class PolicyReviewStatusEnum(proto.Message): + r"""Container for enum describing possible policy review + statuses. + + """ + + class PolicyReviewStatus(proto.Enum): + r"""The possible policy review statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REVIEW_IN_PROGRESS = 2 + REVIEWED = 3 + UNDER_APPEAL = 4 + ELIGIBLE_MAY_SERVE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_topic_entry_type.py b/google/ads/googleads/v12/enums/types/policy_topic_entry_type.py new file mode 100644 index 000000000..f7a0a064b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_topic_entry_type.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyTopicEntryTypeEnum",}, +) + + +class PolicyTopicEntryTypeEnum(proto.Message): + r"""Container for enum describing possible policy topic entry + types. + + """ + + class PolicyTopicEntryType(proto.Enum): + r"""The possible policy topic entry types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PROHIBITED = 2 + LIMITED = 4 + FULLY_LIMITED = 8 + DESCRIPTIVE = 5 + BROADENING = 6 + AREA_OF_INTEREST_ONLY = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_mismatch_url_type.py b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_mismatch_url_type.py new file mode 100644 index 000000000..630539f8a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_mismatch_url_type.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyTopicEvidenceDestinationMismatchUrlTypeEnum",}, +) + + +class PolicyTopicEvidenceDestinationMismatchUrlTypeEnum(proto.Message): + r"""Container for enum describing possible policy topic evidence + destination mismatch url types. + + """ + + class PolicyTopicEvidenceDestinationMismatchUrlType(proto.Enum): + r"""The possible policy topic evidence destination mismatch url + types. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + DISPLAY_URL = 2 + FINAL_URL = 3 + FINAL_MOBILE_URL = 4 + TRACKING_URL = 5 + MOBILE_TRACKING_URL = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_device.py b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_device.py new file mode 100644 index 000000000..7588716ab --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_device.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyTopicEvidenceDestinationNotWorkingDeviceEnum",}, +) + + +class PolicyTopicEvidenceDestinationNotWorkingDeviceEnum(proto.Message): + r"""Container for enum describing possible policy topic evidence + destination not working devices. + + """ + + class PolicyTopicEvidenceDestinationNotWorkingDevice(proto.Enum): + r"""The possible policy topic evidence destination not working + devices. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + DESKTOP = 2 + ANDROID = 3 + IOS = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py new file mode 100644 index 000000000..78aeda137 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum",}, +) + + +class PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum(proto.Message): + r"""Container for enum describing possible policy topic evidence + destination not working DNS error types. + + """ + + class PolicyTopicEvidenceDestinationNotWorkingDnsErrorType(proto.Enum): + r"""The possible policy topic evidence destination not working + DNS error types. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + HOSTNAME_NOT_FOUND = 2 + GOOGLE_CRAWLER_DNS_ISSUE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/positive_geo_target_type.py b/google/ads/googleads/v12/enums/types/positive_geo_target_type.py new file mode 100644 index 000000000..4ff0714d2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/positive_geo_target_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PositiveGeoTargetTypeEnum",}, +) + + +class PositiveGeoTargetTypeEnum(proto.Message): + r"""Container for enum describing possible positive geo target + types. + + """ + + class PositiveGeoTargetType(proto.Enum): + r"""The possible positive geo target types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PRESENCE_OR_INTEREST = 5 + SEARCH_INTEREST = 6 + PRESENCE = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/preferred_content_type.py b/google/ads/googleads/v12/enums/types/preferred_content_type.py new file mode 100644 index 000000000..0f93f5d37 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/preferred_content_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PreferredContentTypeEnum",}, +) + + +class PreferredContentTypeEnum(proto.Message): + r"""Container for enumeration of preferred content criterion + type. + + """ + + class PreferredContentType(proto.Enum): + r"""Enumerates preferred content criterion type.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + YOUTUBE_TOP_CONTENT = 400 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/price_extension_price_qualifier.py b/google/ads/googleads/v12/enums/types/price_extension_price_qualifier.py new file mode 100644 index 000000000..667e62d04 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/price_extension_price_qualifier.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PriceExtensionPriceQualifierEnum",}, +) + + +class PriceExtensionPriceQualifierEnum(proto.Message): + r"""Container for enum describing a price extension price + qualifier. + + """ + + class PriceExtensionPriceQualifier(proto.Enum): + r"""Enums of price extension price qualifier.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FROM = 2 + UP_TO = 3 + AVERAGE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/price_extension_price_unit.py b/google/ads/googleads/v12/enums/types/price_extension_price_unit.py new file mode 100644 index 000000000..9d0679b4d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/price_extension_price_unit.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PriceExtensionPriceUnitEnum",}, +) + + +class PriceExtensionPriceUnitEnum(proto.Message): + r"""Container for enum describing price extension price unit. + """ + + class PriceExtensionPriceUnit(proto.Enum): + r"""Price extension price unit.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PER_HOUR = 2 + PER_DAY = 3 + PER_WEEK = 4 + PER_MONTH = 5 + PER_YEAR = 6 + PER_NIGHT = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/price_extension_type.py b/google/ads/googleads/v12/enums/types/price_extension_type.py new file mode 100644 index 000000000..76b93d8d8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/price_extension_type.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PriceExtensionTypeEnum",}, +) + + +class PriceExtensionTypeEnum(proto.Message): + r"""Container for enum describing types for a price extension. + """ + + class PriceExtensionType(proto.Enum): + r"""Price extension type.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BRANDS = 2 + EVENTS = 3 + LOCATIONS = 4 + NEIGHBORHOODS = 5 + PRODUCT_CATEGORIES = 6 + PRODUCT_TIERS = 7 + SERVICES = 8 + SERVICE_CATEGORIES = 9 + SERVICE_TIERS = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/price_placeholder_field.py b/google/ads/googleads/v12/enums/types/price_placeholder_field.py new file mode 100644 index 000000000..04546e93a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/price_placeholder_field.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PricePlaceholderFieldEnum",}, +) + + +class PricePlaceholderFieldEnum(proto.Message): + r"""Values for Price placeholder fields. + """ + + class PricePlaceholderField(proto.Enum): + r"""Possible values for Price placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TYPE = 2 + PRICE_QUALIFIER = 3 + TRACKING_TEMPLATE = 4 + LANGUAGE = 5 + FINAL_URL_SUFFIX = 6 + ITEM_1_HEADER = 100 + ITEM_1_DESCRIPTION = 101 + ITEM_1_PRICE = 102 + ITEM_1_UNIT = 103 + ITEM_1_FINAL_URLS = 104 + ITEM_1_FINAL_MOBILE_URLS = 105 + ITEM_2_HEADER = 200 + ITEM_2_DESCRIPTION = 201 + ITEM_2_PRICE = 202 + ITEM_2_UNIT = 203 + ITEM_2_FINAL_URLS = 204 + ITEM_2_FINAL_MOBILE_URLS = 205 + ITEM_3_HEADER = 300 + ITEM_3_DESCRIPTION = 301 + ITEM_3_PRICE = 302 + ITEM_3_UNIT = 303 + ITEM_3_FINAL_URLS = 304 + ITEM_3_FINAL_MOBILE_URLS = 305 + ITEM_4_HEADER = 400 + ITEM_4_DESCRIPTION = 401 + ITEM_4_PRICE = 402 + ITEM_4_UNIT = 403 + ITEM_4_FINAL_URLS = 404 + ITEM_4_FINAL_MOBILE_URLS = 405 + ITEM_5_HEADER = 500 + ITEM_5_DESCRIPTION = 501 + ITEM_5_PRICE = 502 + ITEM_5_UNIT = 503 + ITEM_5_FINAL_URLS = 504 + ITEM_5_FINAL_MOBILE_URLS = 505 + ITEM_6_HEADER = 600 + ITEM_6_DESCRIPTION = 601 + ITEM_6_PRICE = 602 + ITEM_6_UNIT = 603 + ITEM_6_FINAL_URLS = 604 + ITEM_6_FINAL_MOBILE_URLS = 605 + ITEM_7_HEADER = 700 + ITEM_7_DESCRIPTION = 701 + ITEM_7_PRICE = 702 + ITEM_7_UNIT = 703 + ITEM_7_FINAL_URLS = 704 + ITEM_7_FINAL_MOBILE_URLS = 705 + ITEM_8_HEADER = 800 + ITEM_8_DESCRIPTION = 801 + ITEM_8_PRICE = 802 + ITEM_8_UNIT = 803 + ITEM_8_FINAL_URLS = 804 + ITEM_8_FINAL_MOBILE_URLS = 805 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_bidding_category_level.py b/google/ads/googleads/v12/enums/types/product_bidding_category_level.py new file mode 100644 index 000000000..e3c1ee2c9 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_bidding_category_level.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductBiddingCategoryLevelEnum",}, +) + + +class ProductBiddingCategoryLevelEnum(proto.Message): + r"""Level of a product bidding category. + """ + + class ProductBiddingCategoryLevel(proto.Enum): + r"""Enum describing the level of the product bidding category.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LEVEL1 = 2 + LEVEL2 = 3 + LEVEL3 = 4 + LEVEL4 = 5 + LEVEL5 = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_bidding_category_status.py b/google/ads/googleads/v12/enums/types/product_bidding_category_status.py new file mode 100644 index 000000000..2f82f4331 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_bidding_category_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductBiddingCategoryStatusEnum",}, +) + + +class ProductBiddingCategoryStatusEnum(proto.Message): + r"""Status of the product bidding category. + """ + + class ProductBiddingCategoryStatus(proto.Enum): + r"""Enum describing the status of the product bidding category.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACTIVE = 2 + OBSOLETE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_channel.py b/google/ads/googleads/v12/enums/types/product_channel.py new file mode 100644 index 000000000..b20b4b6e4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_channel.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductChannelEnum",}, +) + + +class ProductChannelEnum(proto.Message): + r"""Locality of a product offer. + """ + + class ProductChannel(proto.Enum): + r"""Enum describing the locality of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ONLINE = 2 + LOCAL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_channel_exclusivity.py b/google/ads/googleads/v12/enums/types/product_channel_exclusivity.py new file mode 100644 index 000000000..3e3c3dab2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_channel_exclusivity.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductChannelExclusivityEnum",}, +) + + +class ProductChannelExclusivityEnum(proto.Message): + r"""Availability of a product offer. + """ + + class ProductChannelExclusivity(proto.Enum): + r"""Enum describing the availability of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SINGLE_CHANNEL = 2 + MULTI_CHANNEL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_condition.py b/google/ads/googleads/v12/enums/types/product_condition.py new file mode 100644 index 000000000..16aedac7d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_condition.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductConditionEnum",}, +) + + +class ProductConditionEnum(proto.Message): + r"""Condition of a product offer. + """ + + class ProductCondition(proto.Enum): + r"""Enum describing the condition of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NEW = 3 + REFURBISHED = 4 + USED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_custom_attribute_index.py b/google/ads/googleads/v12/enums/types/product_custom_attribute_index.py new file mode 100644 index 000000000..932c9af7a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_custom_attribute_index.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductCustomAttributeIndexEnum",}, +) + + +class ProductCustomAttributeIndexEnum(proto.Message): + r"""Container for enum describing the index of the product custom + attribute. + + """ + + class ProductCustomAttributeIndex(proto.Enum): + r"""The index of the product custom attribute.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INDEX0 = 7 + INDEX1 = 8 + INDEX2 = 9 + INDEX3 = 10 + INDEX4 = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/product_type_level.py b/google/ads/googleads/v12/enums/types/product_type_level.py new file mode 100644 index 000000000..18afc1d97 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/product_type_level.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProductTypeLevelEnum",}, +) + + +class ProductTypeLevelEnum(proto.Message): + r"""Level of the type of a product offer. + """ + + class ProductTypeLevel(proto.Enum): + r"""Enum describing the level of the type of a product offer.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LEVEL1 = 7 + LEVEL2 = 8 + LEVEL3 = 9 + LEVEL4 = 10 + LEVEL5 = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/promotion_extension_discount_modifier.py b/google/ads/googleads/v12/enums/types/promotion_extension_discount_modifier.py new file mode 100644 index 000000000..f0a76a56d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/promotion_extension_discount_modifier.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PromotionExtensionDiscountModifierEnum",}, +) + + +class PromotionExtensionDiscountModifierEnum(proto.Message): + r"""Container for enum describing possible a promotion extension + discount modifier. + + """ + + class PromotionExtensionDiscountModifier(proto.Enum): + r"""A promotion extension discount modifier.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UP_TO = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/promotion_extension_occasion.py b/google/ads/googleads/v12/enums/types/promotion_extension_occasion.py new file mode 100644 index 000000000..c250316bc --- /dev/null +++ b/google/ads/googleads/v12/enums/types/promotion_extension_occasion.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PromotionExtensionOccasionEnum",}, +) + + +class PromotionExtensionOccasionEnum(proto.Message): + r"""Container for enum describing a promotion extension occasion. + For more information about the occasions check: + https://support.google.com/google-ads/answer/7367521 + + """ + + class PromotionExtensionOccasion(proto.Enum): + r"""A promotion extension occasion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NEW_YEARS = 2 + CHINESE_NEW_YEAR = 3 + VALENTINES_DAY = 4 + EASTER = 5 + MOTHERS_DAY = 6 + FATHERS_DAY = 7 + LABOR_DAY = 8 + BACK_TO_SCHOOL = 9 + HALLOWEEN = 10 + BLACK_FRIDAY = 11 + CYBER_MONDAY = 12 + CHRISTMAS = 13 + BOXING_DAY = 14 + INDEPENDENCE_DAY = 15 + NATIONAL_DAY = 16 + END_OF_SEASON = 17 + WINTER_SALE = 18 + SUMMER_SALE = 19 + FALL_SALE = 20 + SPRING_SALE = 21 + RAMADAN = 22 + EID_AL_FITR = 23 + EID_AL_ADHA = 24 + SINGLES_DAY = 25 + WOMENS_DAY = 26 + HOLI = 27 + PARENTS_DAY = 28 + ST_NICHOLAS_DAY = 29 + CARNIVAL = 30 + EPIPHANY = 31 + ROSH_HASHANAH = 32 + PASSOVER = 33 + HANUKKAH = 34 + DIWALI = 35 + NAVRATRI = 36 + SONGKRAN = 37 + YEAR_END_GIFT = 38 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/promotion_placeholder_field.py b/google/ads/googleads/v12/enums/types/promotion_placeholder_field.py new file mode 100644 index 000000000..0249393d8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/promotion_placeholder_field.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"PromotionPlaceholderFieldEnum",}, +) + + +class PromotionPlaceholderFieldEnum(proto.Message): + r"""Values for Promotion placeholder fields. + """ + + class PromotionPlaceholderField(proto.Enum): + r"""Possible values for Promotion placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PROMOTION_TARGET = 2 + DISCOUNT_MODIFIER = 3 + PERCENT_OFF = 4 + MONEY_AMOUNT_OFF = 5 + PROMOTION_CODE = 6 + ORDERS_OVER_AMOUNT = 7 + PROMOTION_START = 8 + PROMOTION_END = 9 + OCCASION = 10 + FINAL_URLS = 11 + FINAL_MOBILE_URLS = 12 + TRACKING_URL = 13 + LANGUAGE = 14 + FINAL_URL_SUFFIX = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/proximity_radius_units.py b/google/ads/googleads/v12/enums/types/proximity_radius_units.py new file mode 100644 index 000000000..9d0aaa009 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/proximity_radius_units.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ProximityRadiusUnitsEnum",}, +) + + +class ProximityRadiusUnitsEnum(proto.Message): + r"""Container for enum describing unit of radius in proximity. + """ + + class ProximityRadiusUnits(proto.Enum): + r"""The unit of radius distance in proximity (for example, MILES)""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MILES = 2 + KILOMETERS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/quality_score_bucket.py b/google/ads/googleads/v12/enums/types/quality_score_bucket.py new file mode 100644 index 000000000..9dc521ec8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/quality_score_bucket.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"QualityScoreBucketEnum",}, +) + + +class QualityScoreBucketEnum(proto.Message): + r"""The relative performance compared to other advertisers. + """ + + class QualityScoreBucket(proto.Enum): + r"""Enum listing the possible quality score buckets.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BELOW_AVERAGE = 2 + AVERAGE = 3 + ABOVE_AVERAGE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/reach_plan_age_range.py b/google/ads/googleads/v12/enums/types/reach_plan_age_range.py new file mode 100644 index 000000000..72102bcc7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/reach_plan_age_range.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ReachPlanAgeRangeEnum",}, +) + + +class ReachPlanAgeRangeEnum(proto.Message): + r"""Message describing plannable age ranges. + """ + + class ReachPlanAgeRange(proto.Enum): + r"""Possible plannable age range values.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AGE_RANGE_18_24 = 503001 + AGE_RANGE_18_34 = 2 + AGE_RANGE_18_44 = 3 + AGE_RANGE_18_49 = 4 + AGE_RANGE_18_54 = 5 + AGE_RANGE_18_64 = 6 + AGE_RANGE_18_65_UP = 7 + AGE_RANGE_21_34 = 8 + AGE_RANGE_25_34 = 503002 + AGE_RANGE_25_44 = 9 + AGE_RANGE_25_49 = 10 + AGE_RANGE_25_54 = 11 + AGE_RANGE_25_64 = 12 + AGE_RANGE_25_65_UP = 13 + AGE_RANGE_35_44 = 503003 + AGE_RANGE_35_49 = 14 + AGE_RANGE_35_54 = 15 + AGE_RANGE_35_64 = 16 + AGE_RANGE_35_65_UP = 17 + AGE_RANGE_45_54 = 503004 + AGE_RANGE_45_64 = 18 + AGE_RANGE_45_65_UP = 19 + AGE_RANGE_50_65_UP = 20 + AGE_RANGE_55_64 = 503005 + AGE_RANGE_55_65_UP = 21 + AGE_RANGE_65_UP = 503006 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/reach_plan_network.py b/google/ads/googleads/v12/enums/types/reach_plan_network.py new file mode 100644 index 000000000..977d03207 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/reach_plan_network.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ReachPlanNetworkEnum",}, +) + + +class ReachPlanNetworkEnum(proto.Message): + r"""Container for enum describing plannable networks. + """ + + class ReachPlanNetwork(proto.Enum): + r"""Possible plannable network values.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + YOUTUBE = 2 + GOOGLE_VIDEO_PARTNERS = 3 + YOUTUBE_AND_GOOGLE_VIDEO_PARTNERS = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/real_estate_placeholder_field.py b/google/ads/googleads/v12/enums/types/real_estate_placeholder_field.py new file mode 100644 index 000000000..c4e977e95 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/real_estate_placeholder_field.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"RealEstatePlaceholderFieldEnum",}, +) + + +class RealEstatePlaceholderFieldEnum(proto.Message): + r"""Values for Real Estate placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class RealEstatePlaceholderField(proto.Enum): + r"""Possible values for Real Estate placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LISTING_ID = 2 + LISTING_NAME = 3 + CITY_NAME = 4 + DESCRIPTION = 5 + ADDRESS = 6 + PRICE = 7 + FORMATTED_PRICE = 8 + IMAGE_URL = 9 + PROPERTY_TYPE = 10 + LISTING_TYPE = 11 + CONTEXTUAL_KEYWORDS = 12 + FINAL_URLS = 13 + FINAL_MOBILE_URLS = 14 + TRACKING_URL = 15 + ANDROID_APP_LINK = 16 + SIMILAR_LISTING_IDS = 17 + IOS_APP_LINK = 18 + IOS_APP_STORE_ID = 19 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/recommendation_type.py b/google/ads/googleads/v12/enums/types/recommendation_type.py new file mode 100644 index 000000000..ef1530770 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/recommendation_type.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"RecommendationTypeEnum",}, +) + + +class RecommendationTypeEnum(proto.Message): + r"""Container for enum describing types of recommendations. + """ + + class RecommendationType(proto.Enum): + r"""Types of recommendations.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN_BUDGET = 2 + KEYWORD = 3 + TEXT_AD = 4 + TARGET_CPA_OPT_IN = 5 + MAXIMIZE_CONVERSIONS_OPT_IN = 6 + ENHANCED_CPC_OPT_IN = 7 + SEARCH_PARTNERS_OPT_IN = 8 + MAXIMIZE_CLICKS_OPT_IN = 9 + OPTIMIZE_AD_ROTATION = 10 + CALLOUT_EXTENSION = 11 + SITELINK_EXTENSION = 12 + CALL_EXTENSION = 13 + KEYWORD_MATCH_TYPE = 14 + MOVE_UNUSED_BUDGET = 15 + FORECASTING_CAMPAIGN_BUDGET = 16 + TARGET_ROAS_OPT_IN = 17 + RESPONSIVE_SEARCH_AD = 18 + MARGINAL_ROI_CAMPAIGN_BUDGET = 19 + USE_BROAD_MATCH_KEYWORD = 20 + RESPONSIVE_SEARCH_AD_ASSET = 21 + UPGRADE_SMART_SHOPPING_CAMPAIGN_TO_PERFORMANCE_MAX = 22 + RESPONSIVE_SEARCH_AD_IMPROVE_AD_STRENGTH = 23 + DISPLAY_EXPANSION_OPT_IN = 24 + UPGRADE_LOCAL_CAMPAIGN_TO_PERFORMANCE_MAX = 25 + RAISE_TARGET_CPA_BID_TOO_LOW = 26 + FORECASTING_SET_TARGET_ROAS = 27 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/resource_change_operation.py b/google/ads/googleads/v12/enums/types/resource_change_operation.py new file mode 100644 index 000000000..d9bf38178 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/resource_change_operation.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ResourceChangeOperationEnum",}, +) + + +class ResourceChangeOperationEnum(proto.Message): + r"""Container for enum describing resource change operations + in the ChangeEvent resource. + + """ + + class ResourceChangeOperation(proto.Enum): + r"""The operation on the changed resource in change_event resource.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CREATE = 2 + UPDATE = 3 + REMOVE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/resource_limit_type.py b/google/ads/googleads/v12/enums/types/resource_limit_type.py new file mode 100644 index 000000000..c46f0105b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/resource_limit_type.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ResourceLimitTypeEnum",}, +) + + +class ResourceLimitTypeEnum(proto.Message): + r"""Container for enum describing possible resource limit types. + """ + + class ResourceLimitType(proto.Enum): + r"""Resource limit type.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGNS_PER_CUSTOMER = 2 + BASE_CAMPAIGNS_PER_CUSTOMER = 3 + EXPERIMENT_CAMPAIGNS_PER_CUSTOMER = 105 + HOTEL_CAMPAIGNS_PER_CUSTOMER = 4 + SMART_SHOPPING_CAMPAIGNS_PER_CUSTOMER = 5 + AD_GROUPS_PER_CAMPAIGN = 6 + AD_GROUPS_PER_SHOPPING_CAMPAIGN = 8 + AD_GROUPS_PER_HOTEL_CAMPAIGN = 9 + REPORTING_AD_GROUPS_PER_LOCAL_CAMPAIGN = 10 + REPORTING_AD_GROUPS_PER_APP_CAMPAIGN = 11 + MANAGED_AD_GROUPS_PER_SMART_CAMPAIGN = 52 + AD_GROUP_CRITERIA_PER_CUSTOMER = 12 + BASE_AD_GROUP_CRITERIA_PER_CUSTOMER = 13 + EXPERIMENT_AD_GROUP_CRITERIA_PER_CUSTOMER = 107 + AD_GROUP_CRITERIA_PER_CAMPAIGN = 14 + CAMPAIGN_CRITERIA_PER_CUSTOMER = 15 + BASE_CAMPAIGN_CRITERIA_PER_CUSTOMER = 16 + EXPERIMENT_CAMPAIGN_CRITERIA_PER_CUSTOMER = 108 + WEBPAGE_CRITERIA_PER_CUSTOMER = 17 + BASE_WEBPAGE_CRITERIA_PER_CUSTOMER = 18 + EXPERIMENT_WEBPAGE_CRITERIA_PER_CUSTOMER = 19 + COMBINED_AUDIENCE_CRITERIA_PER_AD_GROUP = 20 + CUSTOMER_NEGATIVE_PLACEMENT_CRITERIA_PER_CUSTOMER = 21 + CUSTOMER_NEGATIVE_YOUTUBE_CHANNEL_CRITERIA_PER_CUSTOMER = 22 + CRITERIA_PER_AD_GROUP = 23 + LISTING_GROUPS_PER_AD_GROUP = 24 + EXPLICITLY_SHARED_BUDGETS_PER_CUSTOMER = 25 + IMPLICITLY_SHARED_BUDGETS_PER_CUSTOMER = 26 + COMBINED_AUDIENCE_CRITERIA_PER_CAMPAIGN = 27 + NEGATIVE_KEYWORDS_PER_CAMPAIGN = 28 + NEGATIVE_PLACEMENTS_PER_CAMPAIGN = 29 + GEO_TARGETS_PER_CAMPAIGN = 30 + NEGATIVE_IP_BLOCKS_PER_CAMPAIGN = 32 + PROXIMITIES_PER_CAMPAIGN = 33 + LISTING_SCOPES_PER_SHOPPING_CAMPAIGN = 34 + LISTING_SCOPES_PER_NON_SHOPPING_CAMPAIGN = 35 + NEGATIVE_KEYWORDS_PER_SHARED_SET = 36 + NEGATIVE_PLACEMENTS_PER_SHARED_SET = 37 + SHARED_SETS_PER_CUSTOMER_FOR_TYPE_DEFAULT = 40 + SHARED_SETS_PER_CUSTOMER_FOR_NEGATIVE_PLACEMENT_LIST_LOWER = 41 + HOTEL_ADVANCE_BOOKING_WINDOW_BID_MODIFIERS_PER_AD_GROUP = 44 + BIDDING_STRATEGIES_PER_CUSTOMER = 45 + BASIC_USER_LISTS_PER_CUSTOMER = 47 + LOGICAL_USER_LISTS_PER_CUSTOMER = 48 + RULE_BASED_USER_LISTS_PER_CUSTOMER = 153 + BASE_AD_GROUP_ADS_PER_CUSTOMER = 53 + EXPERIMENT_AD_GROUP_ADS_PER_CUSTOMER = 54 + AD_GROUP_ADS_PER_CAMPAIGN = 55 + TEXT_AND_OTHER_ADS_PER_AD_GROUP = 56 + IMAGE_ADS_PER_AD_GROUP = 57 + SHOPPING_SMART_ADS_PER_AD_GROUP = 58 + RESPONSIVE_SEARCH_ADS_PER_AD_GROUP = 59 + APP_ADS_PER_AD_GROUP = 60 + APP_ENGAGEMENT_ADS_PER_AD_GROUP = 61 + LOCAL_ADS_PER_AD_GROUP = 62 + VIDEO_ADS_PER_AD_GROUP = 63 + LEAD_FORM_CAMPAIGN_ASSETS_PER_CAMPAIGN = 143 + PROMOTION_CUSTOMER_ASSETS_PER_CUSTOMER = 79 + PROMOTION_CAMPAIGN_ASSETS_PER_CAMPAIGN = 80 + PROMOTION_AD_GROUP_ASSETS_PER_AD_GROUP = 81 + CALLOUT_CUSTOMER_ASSETS_PER_CUSTOMER = 134 + CALLOUT_CAMPAIGN_ASSETS_PER_CAMPAIGN = 135 + CALLOUT_AD_GROUP_ASSETS_PER_AD_GROUP = 136 + SITELINK_CUSTOMER_ASSETS_PER_CUSTOMER = 137 + SITELINK_CAMPAIGN_ASSETS_PER_CAMPAIGN = 138 + SITELINK_AD_GROUP_ASSETS_PER_AD_GROUP = 139 + STRUCTURED_SNIPPET_CUSTOMER_ASSETS_PER_CUSTOMER = 140 + STRUCTURED_SNIPPET_CAMPAIGN_ASSETS_PER_CAMPAIGN = 141 + STRUCTURED_SNIPPET_AD_GROUP_ASSETS_PER_AD_GROUP = 142 + MOBILE_APP_CUSTOMER_ASSETS_PER_CUSTOMER = 144 + MOBILE_APP_CAMPAIGN_ASSETS_PER_CAMPAIGN = 145 + MOBILE_APP_AD_GROUP_ASSETS_PER_AD_GROUP = 146 + HOTEL_CALLOUT_CUSTOMER_ASSETS_PER_CUSTOMER = 147 + HOTEL_CALLOUT_CAMPAIGN_ASSETS_PER_CAMPAIGN = 148 + HOTEL_CALLOUT_AD_GROUP_ASSETS_PER_AD_GROUP = 149 + CALL_CUSTOMER_ASSETS_PER_CUSTOMER = 150 + CALL_CAMPAIGN_ASSETS_PER_CAMPAIGN = 151 + CALL_AD_GROUP_ASSETS_PER_AD_GROUP = 152 + PRICE_CUSTOMER_ASSETS_PER_CUSTOMER = 154 + PRICE_CAMPAIGN_ASSETS_PER_CAMPAIGN = 155 + PRICE_AD_GROUP_ASSETS_PER_AD_GROUP = 156 + AD_IMAGE_CAMPAIGN_ASSETS_PER_CAMPAIGN = 175 + AD_IMAGE_AD_GROUP_ASSETS_PER_AD_GROUP = 176 + PAGE_FEED_ASSET_SETS_PER_CUSTOMER = 157 + DYNAMIC_EDUCATION_FEED_ASSET_SETS_PER_CUSTOMER = 158 + ASSETS_PER_PAGE_FEED_ASSET_SET = 159 + ASSETS_PER_DYNAMIC_EDUCATION_FEED_ASSET_SET = 160 + DYNAMIC_REAL_ESTATE_ASSET_SETS_PER_CUSTOMER = 161 + ASSETS_PER_DYNAMIC_REAL_ESTATE_ASSET_SET = 162 + DYNAMIC_CUSTOM_ASSET_SETS_PER_CUSTOMER = 163 + ASSETS_PER_DYNAMIC_CUSTOM_ASSET_SET = 164 + DYNAMIC_HOTELS_AND_RENTALS_ASSET_SETS_PER_CUSTOMER = 165 + ASSETS_PER_DYNAMIC_HOTELS_AND_RENTALS_ASSET_SET = 166 + DYNAMIC_LOCAL_ASSET_SETS_PER_CUSTOMER = 167 + ASSETS_PER_DYNAMIC_LOCAL_ASSET_SET = 168 + DYNAMIC_FLIGHTS_ASSET_SETS_PER_CUSTOMER = 169 + ASSETS_PER_DYNAMIC_FLIGHTS_ASSET_SET = 170 + DYNAMIC_TRAVEL_ASSET_SETS_PER_CUSTOMER = 171 + ASSETS_PER_DYNAMIC_TRAVEL_ASSET_SET = 172 + DYNAMIC_JOBS_ASSET_SETS_PER_CUSTOMER = 173 + ASSETS_PER_DYNAMIC_JOBS_ASSET_SET = 174 + VERSIONS_PER_AD = 82 + USER_FEEDS_PER_CUSTOMER = 90 + SYSTEM_FEEDS_PER_CUSTOMER = 91 + FEED_ATTRIBUTES_PER_FEED = 92 + FEED_ITEMS_PER_CUSTOMER = 94 + CAMPAIGN_FEEDS_PER_CUSTOMER = 95 + BASE_CAMPAIGN_FEEDS_PER_CUSTOMER = 96 + EXPERIMENT_CAMPAIGN_FEEDS_PER_CUSTOMER = 109 + AD_GROUP_FEEDS_PER_CUSTOMER = 97 + BASE_AD_GROUP_FEEDS_PER_CUSTOMER = 98 + EXPERIMENT_AD_GROUP_FEEDS_PER_CUSTOMER = 110 + AD_GROUP_FEEDS_PER_CAMPAIGN = 99 + FEED_ITEM_SETS_PER_CUSTOMER = 100 + FEED_ITEMS_PER_FEED_ITEM_SET = 101 + CAMPAIGN_EXPERIMENTS_PER_CUSTOMER = 112 + EXPERIMENT_ARMS_PER_VIDEO_EXPERIMENT = 113 + OWNED_LABELS_PER_CUSTOMER = 115 + LABELS_PER_CAMPAIGN = 117 + LABELS_PER_AD_GROUP = 118 + LABELS_PER_AD_GROUP_AD = 119 + LABELS_PER_AD_GROUP_CRITERION = 120 + TARGET_CUSTOMERS_PER_LABEL = 121 + KEYWORD_PLANS_PER_USER_PER_CUSTOMER = 122 + KEYWORD_PLAN_AD_GROUP_KEYWORDS_PER_KEYWORD_PLAN = 123 + KEYWORD_PLAN_AD_GROUPS_PER_KEYWORD_PLAN = 124 + KEYWORD_PLAN_NEGATIVE_KEYWORDS_PER_KEYWORD_PLAN = 125 + KEYWORD_PLAN_CAMPAIGNS_PER_KEYWORD_PLAN = 126 + CONVERSION_ACTIONS_PER_CUSTOMER = 128 + BATCH_JOB_OPERATIONS_PER_JOB = 130 + BATCH_JOBS_PER_CUSTOMER = 131 + HOTEL_CHECK_IN_DATE_RANGE_BID_MODIFIERS_PER_AD_GROUP = 132 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/response_content_type.py b/google/ads/googleads/v12/enums/types/response_content_type.py new file mode 100644 index 000000000..691b34045 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/response_content_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ResponseContentTypeEnum",}, +) + + +class ResponseContentTypeEnum(proto.Message): + r"""Container for possible response content types. + """ + + class ResponseContentType(proto.Enum): + r"""Possible response content types.""" + UNSPECIFIED = 0 + RESOURCE_NAME_ONLY = 1 + MUTABLE_RESOURCE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/search_engine_results_page_type.py b/google/ads/googleads/v12/enums/types/search_engine_results_page_type.py new file mode 100644 index 000000000..14bf84d02 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/search_engine_results_page_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SearchEngineResultsPageTypeEnum",}, +) + + +class SearchEngineResultsPageTypeEnum(proto.Message): + r"""The type of the search engine results page. + """ + + class SearchEngineResultsPageType(proto.Enum): + r"""The type of the search engine results page.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADS_ONLY = 2 + ORGANIC_ONLY = 3 + ADS_AND_ORGANIC = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/search_term_match_type.py b/google/ads/googleads/v12/enums/types/search_term_match_type.py new file mode 100644 index 000000000..b3056dff9 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/search_term_match_type.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SearchTermMatchTypeEnum",}, +) + + +class SearchTermMatchTypeEnum(proto.Message): + r"""Container for enum describing match types for a keyword + triggering an ad. + + """ + + class SearchTermMatchType(proto.Enum): + r"""Possible match types for a keyword triggering an ad, + including variants. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + BROAD = 2 + EXACT = 3 + PHRASE = 4 + NEAR_EXACT = 5 + NEAR_PHRASE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/search_term_targeting_status.py b/google/ads/googleads/v12/enums/types/search_term_targeting_status.py new file mode 100644 index 000000000..b6679547a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/search_term_targeting_status.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SearchTermTargetingStatusEnum",}, +) + + +class SearchTermTargetingStatusEnum(proto.Message): + r"""Container for enum indicating whether a search term is one of + your targeted or excluded keywords. + + """ + + class SearchTermTargetingStatus(proto.Enum): + r"""Indicates whether the search term is one of your targeted or + excluded keywords. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ADDED = 2 + EXCLUDED = 3 + ADDED_EXCLUDED = 4 + NONE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/seasonality_event_scope.py b/google/ads/googleads/v12/enums/types/seasonality_event_scope.py new file mode 100644 index 000000000..12ace274d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/seasonality_event_scope.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SeasonalityEventScopeEnum",}, +) + + +class SeasonalityEventScopeEnum(proto.Message): + r"""Message describing seasonality event scopes. The two types of + seasonality events are BiddingSeasonalityAdjustments and + BiddingDataExclusions. + + """ + + class SeasonalityEventScope(proto.Enum): + r"""The possible scopes of a Seasonality Event.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER = 2 + CAMPAIGN = 4 + CHANNEL = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/seasonality_event_status.py b/google/ads/googleads/v12/enums/types/seasonality_event_status.py new file mode 100644 index 000000000..32b13f741 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/seasonality_event_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SeasonalityEventStatusEnum",}, +) + + +class SeasonalityEventStatusEnum(proto.Message): + r"""Message describing seasonality event statuses. The two types + of seasonality events are BiddingSeasonalityAdjustments and + BiddingDataExclusions. + + """ + + class SeasonalityEventStatus(proto.Enum): + r"""The possible statuses of a Seasonality Event.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/served_asset_field_type.py b/google/ads/googleads/v12/enums/types/served_asset_field_type.py new file mode 100644 index 000000000..40e566dc3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/served_asset_field_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ServedAssetFieldTypeEnum",}, +) + + +class ServedAssetFieldTypeEnum(proto.Message): + r"""Container for enum describing possible asset field types. + """ + + class ServedAssetFieldType(proto.Enum): + r"""The possible asset field types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + HEADLINE_1 = 2 + HEADLINE_2 = 3 + HEADLINE_3 = 4 + DESCRIPTION_1 = 5 + DESCRIPTION_2 = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/shared_set_status.py b/google/ads/googleads/v12/enums/types/shared_set_status.py new file mode 100644 index 000000000..0f67c20a7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/shared_set_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SharedSetStatusEnum",}, +) + + +class SharedSetStatusEnum(proto.Message): + r"""Container for enum describing types of shared set statuses. + """ + + class SharedSetStatus(proto.Enum): + r"""Enum listing the possible shared set statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + REMOVED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/shared_set_type.py b/google/ads/googleads/v12/enums/types/shared_set_type.py new file mode 100644 index 000000000..7ff33a1a4 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/shared_set_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SharedSetTypeEnum",}, +) + + +class SharedSetTypeEnum(proto.Message): + r"""Container for enum describing types of shared sets. + """ + + class SharedSetType(proto.Enum): + r"""Enum listing the possible shared set types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NEGATIVE_KEYWORDS = 2 + NEGATIVE_PLACEMENTS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/simulation_modification_method.py b/google/ads/googleads/v12/enums/types/simulation_modification_method.py new file mode 100644 index 000000000..3a228f722 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/simulation_modification_method.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SimulationModificationMethodEnum",}, +) + + +class SimulationModificationMethodEnum(proto.Message): + r"""Container for enum describing the method by which a + simulation modifies a field. + + """ + + class SimulationModificationMethod(proto.Enum): + r"""Enum describing the method by which a simulation modifies a + field. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + UNIFORM = 2 + DEFAULT = 3 + SCALING = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/simulation_type.py b/google/ads/googleads/v12/enums/types/simulation_type.py new file mode 100644 index 000000000..573cb37ff --- /dev/null +++ b/google/ads/googleads/v12/enums/types/simulation_type.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SimulationTypeEnum",}, +) + + +class SimulationTypeEnum(proto.Message): + r"""Container for enum describing the field a simulation + modifies. + + """ + + class SimulationType(proto.Enum): + r"""Enum describing the field a simulation modifies.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CPC_BID = 2 + CPV_BID = 3 + TARGET_CPA = 4 + BID_MODIFIER = 5 + TARGET_ROAS = 6 + PERCENT_CPC_BID = 7 + TARGET_IMPRESSION_SHARE = 8 + BUDGET = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/sitelink_placeholder_field.py b/google/ads/googleads/v12/enums/types/sitelink_placeholder_field.py new file mode 100644 index 000000000..d59e3d45b --- /dev/null +++ b/google/ads/googleads/v12/enums/types/sitelink_placeholder_field.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SitelinkPlaceholderFieldEnum",}, +) + + +class SitelinkPlaceholderFieldEnum(proto.Message): + r"""Values for Sitelink placeholder fields. + """ + + class SitelinkPlaceholderField(proto.Enum): + r"""Possible values for Sitelink placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TEXT = 2 + LINE_1 = 3 + LINE_2 = 4 + FINAL_URLS = 5 + FINAL_MOBILE_URLS = 6 + TRACKING_URL = 7 + FINAL_URL_SUFFIX = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/sk_ad_network_ad_event_type.py b/google/ads/googleads/v12/enums/types/sk_ad_network_ad_event_type.py new file mode 100644 index 000000000..74111a7e6 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/sk_ad_network_ad_event_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SkAdNetworkAdEventTypeEnum",}, +) + + +class SkAdNetworkAdEventTypeEnum(proto.Message): + r"""Container for enumeration of SkAdNetwork ad event types. + """ + + class SkAdNetworkAdEventType(proto.Enum): + r"""Enumerates SkAdNetwork ad event types""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNAVAILABLE = 2 + INTERACTION = 3 + VIEW = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/sk_ad_network_attribution_credit.py b/google/ads/googleads/v12/enums/types/sk_ad_network_attribution_credit.py new file mode 100644 index 000000000..892c0450f --- /dev/null +++ b/google/ads/googleads/v12/enums/types/sk_ad_network_attribution_credit.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SkAdNetworkAttributionCreditEnum",}, +) + + +class SkAdNetworkAttributionCreditEnum(proto.Message): + r"""Container for enumeration of SkAdNetwork attribution credits. + """ + + class SkAdNetworkAttributionCredit(proto.Enum): + r"""Enumerates SkAdNetwork attribution credits.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNAVAILABLE = 2 + WON = 3 + CONTRIBUTED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/sk_ad_network_user_type.py b/google/ads/googleads/v12/enums/types/sk_ad_network_user_type.py new file mode 100644 index 000000000..e5e9549f8 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/sk_ad_network_user_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SkAdNetworkUserTypeEnum",}, +) + + +class SkAdNetworkUserTypeEnum(proto.Message): + r"""Container for enumeration of SkAdNetwork user types. + """ + + class SkAdNetworkUserType(proto.Enum): + r"""Enumerates SkAdNetwork user types""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNAVAILABLE = 2 + NEW_INSTALLER = 3 + REINSTALLER = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/slot.py b/google/ads/googleads/v12/enums/types/slot.py new file mode 100644 index 000000000..157998c23 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/slot.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SlotEnum",}, +) + + +class SlotEnum(proto.Message): + r"""Container for enumeration of possible positions of the Ad. + """ + + class Slot(proto.Enum): + r"""Enumerates possible positions of the Ad.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH_SIDE = 2 + SEARCH_TOP = 3 + SEARCH_OTHER = 4 + CONTENT = 5 + SEARCH_PARTNER_TOP = 6 + SEARCH_PARTNER_OTHER = 7 + MIXED = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/spending_limit_type.py b/google/ads/googleads/v12/enums/types/spending_limit_type.py new file mode 100644 index 000000000..f4927bce1 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/spending_limit_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SpendingLimitTypeEnum",}, +) + + +class SpendingLimitTypeEnum(proto.Message): + r"""Message describing spending limit types. + """ + + class SpendingLimitType(proto.Enum): + r"""The possible spending limit types used by certain resources + as an alternative to absolute money values in micros. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INFINITE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/structured_snippet_placeholder_field.py b/google/ads/googleads/v12/enums/types/structured_snippet_placeholder_field.py new file mode 100644 index 000000000..3b794853d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/structured_snippet_placeholder_field.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"StructuredSnippetPlaceholderFieldEnum",}, +) + + +class StructuredSnippetPlaceholderFieldEnum(proto.Message): + r"""Values for Structured Snippet placeholder fields. + """ + + class StructuredSnippetPlaceholderField(proto.Enum): + r"""Possible values for Structured Snippet placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + HEADER = 2 + SNIPPETS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/summary_row_setting.py b/google/ads/googleads/v12/enums/types/summary_row_setting.py new file mode 100644 index 000000000..525c808ba --- /dev/null +++ b/google/ads/googleads/v12/enums/types/summary_row_setting.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SummaryRowSettingEnum",}, +) + + +class SummaryRowSettingEnum(proto.Message): + r"""Indicates summary row setting in request parameter. + """ + + class SummaryRowSetting(proto.Enum): + r"""Enum describing return summary row settings.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_SUMMARY_ROW = 2 + SUMMARY_ROW_WITH_RESULTS = 3 + SUMMARY_ROW_ONLY = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/system_managed_entity_source.py b/google/ads/googleads/v12/enums/types/system_managed_entity_source.py new file mode 100644 index 000000000..f91bdd33e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/system_managed_entity_source.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"SystemManagedResourceSourceEnum",}, +) + + +class SystemManagedResourceSourceEnum(proto.Message): + r"""Container for enum describing possible system managed entity + sources. + + """ + + class SystemManagedResourceSource(proto.Enum): + r"""Enum listing the possible system managed entity sources.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_VARIATIONS = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/target_cpa_opt_in_recommendation_goal.py b/google/ads/googleads/v12/enums/types/target_cpa_opt_in_recommendation_goal.py new file mode 100644 index 000000000..419bed252 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/target_cpa_opt_in_recommendation_goal.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TargetCpaOptInRecommendationGoalEnum",}, +) + + +class TargetCpaOptInRecommendationGoalEnum(proto.Message): + r"""Container for enum describing goals for TargetCpaOptIn + recommendation. + + """ + + class TargetCpaOptInRecommendationGoal(proto.Enum): + r"""Goal of TargetCpaOptIn recommendation.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SAME_COST = 2 + SAME_CONVERSIONS = 3 + SAME_CPA = 4 + CLOSEST_CPA = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/target_impression_share_location.py b/google/ads/googleads/v12/enums/types/target_impression_share_location.py new file mode 100644 index 000000000..870bbf219 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/target_impression_share_location.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TargetImpressionShareLocationEnum",}, +) + + +class TargetImpressionShareLocationEnum(proto.Message): + r"""Container for enum describing where on the first search + results page the automated bidding system should target + impressions for the TargetImpressionShare bidding strategy. + + """ + + class TargetImpressionShareLocation(proto.Enum): + r"""Enum describing possible goals.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ANYWHERE_ON_PAGE = 2 + TOP_OF_PAGE = 3 + ABSOLUTE_TOP_OF_PAGE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/targeting_dimension.py b/google/ads/googleads/v12/enums/types/targeting_dimension.py new file mode 100644 index 000000000..62abf5efa --- /dev/null +++ b/google/ads/googleads/v12/enums/types/targeting_dimension.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TargetingDimensionEnum",}, +) + + +class TargetingDimensionEnum(proto.Message): + r"""The dimensions that can be targeted. + """ + + class TargetingDimension(proto.Enum): + r"""Enum describing possible targeting dimensions.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + KEYWORD = 2 + AUDIENCE = 3 + TOPIC = 4 + GENDER = 5 + AGE_RANGE = 6 + PLACEMENT = 7 + PARENTAL_STATUS = 8 + INCOME_RANGE = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/time_type.py b/google/ads/googleads/v12/enums/types/time_type.py new file mode 100644 index 000000000..f2e15c22e --- /dev/null +++ b/google/ads/googleads/v12/enums/types/time_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TimeTypeEnum",}, +) + + +class TimeTypeEnum(proto.Message): + r"""Message describing time types. + """ + + class TimeType(proto.Enum): + r"""The possible time types used by certain resources as an + alternative to absolute timestamps. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + NOW = 2 + FOREVER = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/tracking_code_page_format.py b/google/ads/googleads/v12/enums/types/tracking_code_page_format.py new file mode 100644 index 000000000..66370e70c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/tracking_code_page_format.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TrackingCodePageFormatEnum",}, +) + + +class TrackingCodePageFormatEnum(proto.Message): + r"""Container for enum describing the format of the web page + where the tracking tag and snippet will be installed. + + """ + + class TrackingCodePageFormat(proto.Enum): + r"""The format of the web page where the tracking tag and snippet + will be installed. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + HTML = 2 + AMP = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/tracking_code_type.py b/google/ads/googleads/v12/enums/types/tracking_code_type.py new file mode 100644 index 000000000..246e35a80 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/tracking_code_type.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TrackingCodeTypeEnum",}, +) + + +class TrackingCodeTypeEnum(proto.Message): + r"""Container for enum describing the type of the generated tag + snippets for tracking conversions. + + """ + + class TrackingCodeType(proto.Enum): + r"""The type of the generated tag snippets for tracking + conversions. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + WEBPAGE = 2 + WEBPAGE_ONCLICK = 3 + CLICK_TO_CALL = 4 + WEBSITE_CALL = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/travel_placeholder_field.py b/google/ads/googleads/v12/enums/types/travel_placeholder_field.py new file mode 100644 index 000000000..eb1fedae3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/travel_placeholder_field.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"TravelPlaceholderFieldEnum",}, +) + + +class TravelPlaceholderFieldEnum(proto.Message): + r"""Values for Travel placeholder fields. + For more information about dynamic remarketing feeds, see + https://support.google.com/google-ads/answer/6053288. + + """ + + class TravelPlaceholderField(proto.Enum): + r"""Possible values for Travel placeholder fields.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DESTINATION_ID = 2 + ORIGIN_ID = 3 + TITLE = 4 + DESTINATION_NAME = 5 + ORIGIN_NAME = 6 + PRICE = 7 + FORMATTED_PRICE = 8 + SALE_PRICE = 9 + FORMATTED_SALE_PRICE = 10 + IMAGE_URL = 11 + CATEGORY = 12 + CONTEXTUAL_KEYWORDS = 13 + DESTINATION_ADDRESS = 14 + FINAL_URL = 15 + FINAL_MOBILE_URLS = 16 + TRACKING_URL = 17 + ANDROID_APP_LINK = 18 + SIMILAR_DESTINATION_IDS = 19 + IOS_APP_LINK = 20 + IOS_APP_STORE_ID = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_identifier_source.py b/google/ads/googleads/v12/enums/types/user_identifier_source.py new file mode 100644 index 000000000..abc4f1094 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_identifier_source.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserIdentifierSourceEnum",}, +) + + +class UserIdentifierSourceEnum(proto.Message): + r"""Container for enum describing the source of the user + identifier for offline Store Sales, click conversion, and + conversion adjustment uploads. + + """ + + class UserIdentifierSource(proto.Enum): + r"""The type of user identifier source for offline Store Sales, + click conversion, and conversion adjustment uploads. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + FIRST_PARTY = 2 + THIRD_PARTY = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_interest_taxonomy_type.py b/google/ads/googleads/v12/enums/types/user_interest_taxonomy_type.py new file mode 100644 index 000000000..b001f6209 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_interest_taxonomy_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserInterestTaxonomyTypeEnum",}, +) + + +class UserInterestTaxonomyTypeEnum(proto.Message): + r"""Message describing a UserInterestTaxonomyType. + """ + + class UserInterestTaxonomyType(proto.Enum): + r"""Enum containing the possible UserInterestTaxonomyTypes.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AFFINITY = 2 + IN_MARKET = 3 + MOBILE_APP_INSTALL_USER = 4 + VERTICAL_GEO = 5 + NEW_SMART_PHONE_USER = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_access_status.py b/google/ads/googleads/v12/enums/types/user_list_access_status.py new file mode 100644 index 000000000..f30d139f9 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_access_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListAccessStatusEnum",}, +) + + +class UserListAccessStatusEnum(proto.Message): + r"""Indicates if this client still has access to the list. + """ + + class UserListAccessStatus(proto.Enum): + r"""Enum containing possible user list access statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENABLED = 2 + DISABLED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_closing_reason.py b/google/ads/googleads/v12/enums/types/user_list_closing_reason.py new file mode 100644 index 000000000..49a638d20 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_closing_reason.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListClosingReasonEnum",}, +) + + +class UserListClosingReasonEnum(proto.Message): + r"""Indicates the reason why the userlist was closed. + This enum is only used when a list is auto-closed by the system. + + """ + + class UserListClosingReason(proto.Enum): + r"""Enum describing possible user list closing reasons.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNUSED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_combined_rule_operator.py b/google/ads/googleads/v12/enums/types/user_list_combined_rule_operator.py new file mode 100644 index 000000000..8d61ba4e1 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_combined_rule_operator.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListCombinedRuleOperatorEnum",}, +) + + +class UserListCombinedRuleOperatorEnum(proto.Message): + r"""Logical operator connecting two rules. + """ + + class UserListCombinedRuleOperator(proto.Enum): + r"""Enum describing possible user list combined rule operators.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AND = 2 + AND_NOT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_crm_data_source_type.py b/google/ads/googleads/v12/enums/types/user_list_crm_data_source_type.py new file mode 100644 index 000000000..e9e1517c7 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_crm_data_source_type.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListCrmDataSourceTypeEnum",}, +) + + +class UserListCrmDataSourceTypeEnum(proto.Message): + r"""Indicates source of Crm upload data. + """ + + class UserListCrmDataSourceType(proto.Enum): + r"""Enum describing possible user list crm data source type.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FIRST_PARTY = 2 + THIRD_PARTY_CREDIT_BUREAU = 3 + THIRD_PARTY_VOTER_FILE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_date_rule_item_operator.py b/google/ads/googleads/v12/enums/types/user_list_date_rule_item_operator.py new file mode 100644 index 000000000..1d3f6346d --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_date_rule_item_operator.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListDateRuleItemOperatorEnum",}, +) + + +class UserListDateRuleItemOperatorEnum(proto.Message): + r"""Supported rule operator for date type. + """ + + class UserListDateRuleItemOperator(proto.Enum): + r"""Enum describing possible user list date rule item operators.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EQUALS = 2 + NOT_EQUALS = 3 + BEFORE = 4 + AFTER = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_flexible_rule_operator.py b/google/ads/googleads/v12/enums/types/user_list_flexible_rule_operator.py new file mode 100644 index 000000000..5ab8a5f58 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_flexible_rule_operator.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListFlexibleRuleOperatorEnum",}, +) + + +class UserListFlexibleRuleOperatorEnum(proto.Message): + r"""Logical operator connecting two rules. + """ + + class UserListFlexibleRuleOperator(proto.Enum): + r"""Enum describing possible user list combined rule operators.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AND = 2 + OR = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_logical_rule_operator.py b/google/ads/googleads/v12/enums/types/user_list_logical_rule_operator.py new file mode 100644 index 000000000..f0fd0f1ec --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_logical_rule_operator.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListLogicalRuleOperatorEnum",}, +) + + +class UserListLogicalRuleOperatorEnum(proto.Message): + r"""The logical operator of the rule. + """ + + class UserListLogicalRuleOperator(proto.Enum): + r"""Enum describing possible user list logical rule operators.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ALL = 2 + ANY = 3 + NONE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_membership_status.py b/google/ads/googleads/v12/enums/types/user_list_membership_status.py new file mode 100644 index 000000000..f1b831adb --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_membership_status.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListMembershipStatusEnum",}, +) + + +class UserListMembershipStatusEnum(proto.Message): + r"""Membership status of this user list. Indicates whether a user + list is open or active. Only open user lists can accumulate more + users and can be used for targeting. + + """ + + class UserListMembershipStatus(proto.Enum): + r"""Enum containing possible user list membership statuses.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPEN = 2 + CLOSED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_number_rule_item_operator.py b/google/ads/googleads/v12/enums/types/user_list_number_rule_item_operator.py new file mode 100644 index 000000000..422462dc2 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_number_rule_item_operator.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListNumberRuleItemOperatorEnum",}, +) + + +class UserListNumberRuleItemOperatorEnum(proto.Message): + r"""Supported rule operator for number type. + """ + + class UserListNumberRuleItemOperator(proto.Enum): + r"""Enum describing possible user list number rule item + operators. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + GREATER_THAN = 2 + GREATER_THAN_OR_EQUAL = 3 + EQUALS = 4 + NOT_EQUALS = 5 + LESS_THAN = 6 + LESS_THAN_OR_EQUAL = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_prepopulation_status.py b/google/ads/googleads/v12/enums/types/user_list_prepopulation_status.py new file mode 100644 index 000000000..74d46f07c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_prepopulation_status.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListPrepopulationStatusEnum",}, +) + + +class UserListPrepopulationStatusEnum(proto.Message): + r"""Indicates status of prepopulation based on the rule. + """ + + class UserListPrepopulationStatus(proto.Enum): + r"""Enum describing possible user list prepopulation status.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REQUESTED = 2 + FINISHED = 3 + FAILED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_rule_type.py b/google/ads/googleads/v12/enums/types/user_list_rule_type.py new file mode 100644 index 000000000..fd27f4057 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_rule_type.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListRuleTypeEnum",}, +) + + +class UserListRuleTypeEnum(proto.Message): + r"""Rule based user list rule type. + """ + + class UserListRuleType(proto.Enum): + r"""Enum describing possible user list rule types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AND_OF_ORS = 2 + OR_OF_ANDS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_size_range.py b/google/ads/googleads/v12/enums/types/user_list_size_range.py new file mode 100644 index 000000000..577704827 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_size_range.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListSizeRangeEnum",}, +) + + +class UserListSizeRangeEnum(proto.Message): + r"""Size range in terms of number of users of a UserList. + """ + + class UserListSizeRange(proto.Enum): + r"""Enum containing possible user list size ranges.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LESS_THAN_FIVE_HUNDRED = 2 + LESS_THAN_ONE_THOUSAND = 3 + ONE_THOUSAND_TO_TEN_THOUSAND = 4 + TEN_THOUSAND_TO_FIFTY_THOUSAND = 5 + FIFTY_THOUSAND_TO_ONE_HUNDRED_THOUSAND = 6 + ONE_HUNDRED_THOUSAND_TO_THREE_HUNDRED_THOUSAND = 7 + THREE_HUNDRED_THOUSAND_TO_FIVE_HUNDRED_THOUSAND = 8 + FIVE_HUNDRED_THOUSAND_TO_ONE_MILLION = 9 + ONE_MILLION_TO_TWO_MILLION = 10 + TWO_MILLION_TO_THREE_MILLION = 11 + THREE_MILLION_TO_FIVE_MILLION = 12 + FIVE_MILLION_TO_TEN_MILLION = 13 + TEN_MILLION_TO_TWENTY_MILLION = 14 + TWENTY_MILLION_TO_THIRTY_MILLION = 15 + THIRTY_MILLION_TO_FIFTY_MILLION = 16 + OVER_FIFTY_MILLION = 17 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_string_rule_item_operator.py b/google/ads/googleads/v12/enums/types/user_list_string_rule_item_operator.py new file mode 100644 index 000000000..376ef5067 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_string_rule_item_operator.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListStringRuleItemOperatorEnum",}, +) + + +class UserListStringRuleItemOperatorEnum(proto.Message): + r"""Supported rule operator for string type. + """ + + class UserListStringRuleItemOperator(proto.Enum): + r"""Enum describing possible user list string rule item + operators. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CONTAINS = 2 + EQUALS = 3 + STARTS_WITH = 4 + ENDS_WITH = 5 + NOT_EQUALS = 6 + NOT_CONTAINS = 7 + NOT_STARTS_WITH = 8 + NOT_ENDS_WITH = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/user_list_type.py b/google/ads/googleads/v12/enums/types/user_list_type.py new file mode 100644 index 000000000..227e91b41 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/user_list_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"UserListTypeEnum",}, +) + + +class UserListTypeEnum(proto.Message): + r"""The user list types. + """ + + class UserListType(proto.Enum): + r"""Enum containing possible user list types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REMARKETING = 2 + LOGICAL = 3 + EXTERNAL_REMARKETING = 4 + RULE_BASED = 5 + SIMILAR = 6 + CRM_BASED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/value_rule_device_type.py b/google/ads/googleads/v12/enums/types/value_rule_device_type.py new file mode 100644 index 000000000..3856bda9c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/value_rule_device_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ValueRuleDeviceTypeEnum",}, +) + + +class ValueRuleDeviceTypeEnum(proto.Message): + r"""Container for enum describing possible device types used in a + conversion value rule. + + """ + + class ValueRuleDeviceType(proto.Enum): + r"""Possible device types used in conversion value rule.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MOBILE = 2 + DESKTOP = 3 + TABLET = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/value_rule_geo_location_match_type.py b/google/ads/googleads/v12/enums/types/value_rule_geo_location_match_type.py new file mode 100644 index 000000000..0ec113337 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/value_rule_geo_location_match_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ValueRuleGeoLocationMatchTypeEnum",}, +) + + +class ValueRuleGeoLocationMatchTypeEnum(proto.Message): + r"""Container for enum describing possible geographic location + matching types used in a conversion value rule. + + """ + + class ValueRuleGeoLocationMatchType(proto.Enum): + r"""Possible geographic location matching types.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ANY = 2 + LOCATION_OF_PRESENCE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/value_rule_operation.py b/google/ads/googleads/v12/enums/types/value_rule_operation.py new file mode 100644 index 000000000..bc54b4a6c --- /dev/null +++ b/google/ads/googleads/v12/enums/types/value_rule_operation.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ValueRuleOperationEnum",}, +) + + +class ValueRuleOperationEnum(proto.Message): + r"""Container for enum describing possible operations for value + rules which are executed when rules are triggered. + + """ + + class ValueRuleOperation(proto.Enum): + r"""Possible operations of the action of a conversion value rule.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADD = 2 + MULTIPLY = 3 + SET = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/value_rule_set_attachment_type.py b/google/ads/googleads/v12/enums/types/value_rule_set_attachment_type.py new file mode 100644 index 000000000..06e259631 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/value_rule_set_attachment_type.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ValueRuleSetAttachmentTypeEnum",}, +) + + +class ValueRuleSetAttachmentTypeEnum(proto.Message): + r"""Container for enum describing where a value rule set is + attached. + + """ + + class ValueRuleSetAttachmentType(proto.Enum): + r"""Possible level where a value rule set is attached.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER = 2 + CAMPAIGN = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/value_rule_set_dimension.py b/google/ads/googleads/v12/enums/types/value_rule_set_dimension.py new file mode 100644 index 000000000..6b4de0dc3 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/value_rule_set_dimension.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"ValueRuleSetDimensionEnum",}, +) + + +class ValueRuleSetDimensionEnum(proto.Message): + r"""Container for enum describing possible dimensions of a + conversion value rule set. + + """ + + class ValueRuleSetDimension(proto.Enum): + r"""Possible dimensions of a conversion value rule set.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + GEO_LOCATION = 2 + DEVICE = 3 + AUDIENCE = 4 + NO_CONDITION = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/vanity_pharma_display_url_mode.py b/google/ads/googleads/v12/enums/types/vanity_pharma_display_url_mode.py new file mode 100644 index 000000000..f1c7b4a51 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/vanity_pharma_display_url_mode.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"VanityPharmaDisplayUrlModeEnum",}, +) + + +class VanityPharmaDisplayUrlModeEnum(proto.Message): + r"""The display mode for vanity pharma URLs. + """ + + class VanityPharmaDisplayUrlMode(proto.Enum): + r"""Enum describing possible display modes for vanity pharma + URLs. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + MANUFACTURER_WEBSITE_URL = 2 + WEBSITE_DESCRIPTION = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/vanity_pharma_text.py b/google/ads/googleads/v12/enums/types/vanity_pharma_text.py new file mode 100644 index 000000000..c5047af15 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/vanity_pharma_text.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"VanityPharmaTextEnum",}, +) + + +class VanityPharmaTextEnum(proto.Message): + r"""The text that will be displayed in display URL of the text ad + when website description is the selected display mode for vanity + pharma URLs. + + """ + + class VanityPharmaText(proto.Enum): + r"""Enum describing possible text.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PRESCRIPTION_TREATMENT_WEBSITE_EN = 2 + PRESCRIPTION_TREATMENT_WEBSITE_ES = 3 + PRESCRIPTION_DEVICE_WEBSITE_EN = 4 + PRESCRIPTION_DEVICE_WEBSITE_ES = 5 + MEDICAL_DEVICE_WEBSITE_EN = 6 + MEDICAL_DEVICE_WEBSITE_ES = 7 + PREVENTATIVE_TREATMENT_WEBSITE_EN = 8 + PREVENTATIVE_TREATMENT_WEBSITE_ES = 9 + PRESCRIPTION_CONTRACEPTION_WEBSITE_EN = 10 + PRESCRIPTION_CONTRACEPTION_WEBSITE_ES = 11 + PRESCRIPTION_VACCINE_WEBSITE_EN = 12 + PRESCRIPTION_VACCINE_WEBSITE_ES = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/video_thumbnail.py b/google/ads/googleads/v12/enums/types/video_thumbnail.py new file mode 100644 index 000000000..1fd580a31 --- /dev/null +++ b/google/ads/googleads/v12/enums/types/video_thumbnail.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"VideoThumbnailEnum",}, +) + + +class VideoThumbnailEnum(proto.Message): + r"""Defines the thumbnail to use for In-Display video ads. Note that + DEFAULT_THUMBNAIL may have been uploaded by the user while + thumbnails 1-3 are auto-generated from the video. + + """ + + class VideoThumbnail(proto.Enum): + r"""Enum listing the possible types of a video thumbnail.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DEFAULT_THUMBNAIL = 2 + THUMBNAIL_1 = 3 + THUMBNAIL_2 = 4 + THUMBNAIL_3 = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/webpage_condition_operand.py b/google/ads/googleads/v12/enums/types/webpage_condition_operand.py new file mode 100644 index 000000000..a746b4ebe --- /dev/null +++ b/google/ads/googleads/v12/enums/types/webpage_condition_operand.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"WebpageConditionOperandEnum",}, +) + + +class WebpageConditionOperandEnum(proto.Message): + r"""Container for enum describing webpage condition operand in + webpage criterion. + + """ + + class WebpageConditionOperand(proto.Enum): + r"""The webpage condition operand in webpage criterion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + URL = 2 + CATEGORY = 3 + PAGE_TITLE = 4 + PAGE_CONTENT = 5 + CUSTOM_LABEL = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/enums/types/webpage_condition_operator.py b/google/ads/googleads/v12/enums/types/webpage_condition_operator.py new file mode 100644 index 000000000..d0857467a --- /dev/null +++ b/google/ads/googleads/v12/enums/types/webpage_condition_operator.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.enums", + marshal="google.ads.googleads.v12", + manifest={"WebpageConditionOperatorEnum",}, +) + + +class WebpageConditionOperatorEnum(proto.Message): + r"""Container for enum describing webpage condition operator in + webpage criterion. + + """ + + class WebpageConditionOperator(proto.Enum): + r"""The webpage condition operator in webpage criterion.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EQUALS = 2 + CONTAINS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/__init__.py b/google/ads/googleads/v12/errors/__init__.py new file mode 100644 index 000000000..6c4cfa257 --- /dev/null +++ b/google/ads/googleads/v12/errors/__init__.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +__all__ = ( + "AccessInvitationErrorEnum", + "AccountBudgetProposalErrorEnum", + "AccountLinkErrorEnum", + "AdCustomizerErrorEnum", + "AdErrorEnum", + "AdGroupAdErrorEnum", + "AdGroupBidModifierErrorEnum", + "AdGroupCriterionCustomizerErrorEnum", + "AdGroupCriterionErrorEnum", + "AdGroupCustomizerErrorEnum", + "AdGroupErrorEnum", + "AdGroupFeedErrorEnum", + "AdParameterErrorEnum", + "AdSharingErrorEnum", + "AdxErrorEnum", + "AssetErrorEnum", + "AssetGroupAssetErrorEnum", + "AssetGroupErrorEnum", + "AssetGroupListingGroupFilterErrorEnum", + "AssetLinkErrorEnum", + "AssetSetAssetErrorEnum", + "AssetSetErrorEnum", + "AssetSetLinkErrorEnum", + "AudienceErrorEnum", + "AudienceInsightsErrorEnum", + "AuthenticationErrorEnum", + "AuthorizationErrorEnum", + "BatchJobErrorEnum", + "BiddingErrorEnum", + "BiddingStrategyErrorEnum", + "BillingSetupErrorEnum", + "CampaignBudgetErrorEnum", + "CampaignConversionGoalErrorEnum", + "CampaignCriterionErrorEnum", + "CampaignCustomizerErrorEnum", + "CampaignDraftErrorEnum", + "CampaignErrorEnum", + "CampaignExperimentErrorEnum", + "CampaignFeedErrorEnum", + "CampaignSharedSetErrorEnum", + "ChangeEventErrorEnum", + "ChangeStatusErrorEnum", + "CollectionSizeErrorEnum", + "ContextErrorEnum", + "ConversionActionErrorEnum", + "ConversionAdjustmentUploadErrorEnum", + "ConversionCustomVariableErrorEnum", + "ConversionGoalCampaignConfigErrorEnum", + "ConversionUploadErrorEnum", + "ConversionValueRuleErrorEnum", + "ConversionValueRuleSetErrorEnum", + "CountryCodeErrorEnum", + "CriterionErrorEnum", + "CurrencyCodeErrorEnum", + "CustomAudienceErrorEnum", + "CustomConversionGoalErrorEnum", + "CustomInterestErrorEnum", + "CustomerClientLinkErrorEnum", + "CustomerCustomizerErrorEnum", + "CustomerErrorEnum", + "CustomerFeedErrorEnum", + "CustomerManagerLinkErrorEnum", + "CustomerUserAccessErrorEnum", + "CustomizerAttributeErrorEnum", + "DatabaseErrorEnum", + "DateErrorEnum", + "DateRangeErrorEnum", + "DistinctErrorEnum", + "EnumErrorEnum", + "ErrorCode", + "ErrorDetails", + "ErrorLocation", + "ExperimentArmErrorEnum", + "ExperimentErrorEnum", + "ExtensionFeedItemErrorEnum", + "ExtensionSettingErrorEnum", + "FeedAttributeReferenceErrorEnum", + "FeedErrorEnum", + "FeedItemErrorEnum", + "FeedItemSetErrorEnum", + "FeedItemSetLinkErrorEnum", + "FeedItemTargetErrorEnum", + "FeedItemValidationErrorEnum", + "FeedMappingErrorEnum", + "FieldErrorEnum", + "FieldMaskErrorEnum", + "FunctionErrorEnum", + "FunctionParsingErrorEnum", + "GeoTargetConstantSuggestionErrorEnum", + "GoogleAdsError", + "GoogleAdsFailure", + "HeaderErrorEnum", + "IdErrorEnum", + "ImageErrorEnum", + "InternalErrorEnum", + "InvoiceErrorEnum", + "KeywordPlanAdGroupErrorEnum", + "KeywordPlanAdGroupKeywordErrorEnum", + "KeywordPlanCampaignErrorEnum", + "KeywordPlanCampaignKeywordErrorEnum", + "KeywordPlanErrorEnum", + "KeywordPlanIdeaErrorEnum", + "LabelErrorEnum", + "LanguageCodeErrorEnum", + "ListOperationErrorEnum", + "ManagerLinkErrorEnum", + "MediaBundleErrorEnum", + "MediaFileErrorEnum", + "MediaUploadErrorEnum", + "MerchantCenterErrorEnum", + "MultiplierErrorEnum", + "MutateErrorEnum", + "NewResourceCreationErrorEnum", + "NotAllowlistedErrorEnum", + "NotEmptyErrorEnum", + "NullErrorEnum", + "OfflineUserDataJobErrorEnum", + "OperationAccessDeniedErrorEnum", + "OperatorErrorEnum", + "PartialFailureErrorEnum", + "PaymentsAccountErrorEnum", + "PolicyFindingDetails", + "PolicyFindingErrorEnum", + "PolicyValidationParameterErrorEnum", + "PolicyViolationDetails", + "PolicyViolationErrorEnum", + "QueryErrorEnum", + "QuotaErrorDetails", + "QuotaErrorEnum", + "RangeErrorEnum", + "ReachPlanErrorEnum", + "RecommendationErrorEnum", + "RegionCodeErrorEnum", + "RequestErrorEnum", + "ResourceAccessDeniedErrorEnum", + "ResourceCountDetails", + "ResourceCountLimitExceededErrorEnum", + "SettingErrorEnum", + "SharedCriterionErrorEnum", + "SharedSetErrorEnum", + "SizeLimitErrorEnum", + "SmartCampaignErrorEnum", + "StringFormatErrorEnum", + "StringLengthErrorEnum", + "ThirdPartyAppAnalyticsLinkErrorEnum", + "TimeZoneErrorEnum", + "UrlFieldErrorEnum", + "UserDataErrorEnum", + "UserListErrorEnum", + "YoutubeVideoRegistrationErrorEnum", +) diff --git a/google/ads/googleads/v12/errors/services/__init__.py b/google/ads/googleads/v12/errors/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/errors/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/errors/types/__init__.py b/google/ads/googleads/v12/errors/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/errors/types/access_invitation_error.py b/google/ads/googleads/v12/errors/types/access_invitation_error.py new file mode 100644 index 000000000..f4504ef51 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/access_invitation_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AccessInvitationErrorEnum",}, +) + + +class AccessInvitationErrorEnum(proto.Message): + r"""Container for enum describing possible AccessInvitation + errors. + + """ + + class AccessInvitationError(proto.Enum): + r"""Enum describing possible AccessInvitation errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_EMAIL_ADDRESS = 2 + EMAIL_ADDRESS_ALREADY_HAS_ACCESS = 3 + INVALID_INVITATION_STATUS = 4 + GOOGLE_CONSUMER_ACCOUNT_NOT_ALLOWED = 5 + INVALID_INVITATION_ID = 6 + EMAIL_ADDRESS_ALREADY_HAS_PENDING_INVITATION = 7 + PENDING_INVITATIONS_LIMIT_EXCEEDED = 8 + EMAIL_DOMAIN_POLICY_VIOLATED = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/account_budget_proposal_error.py b/google/ads/googleads/v12/errors/types/account_budget_proposal_error.py new file mode 100644 index 000000000..bd374ebd4 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/account_budget_proposal_error.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AccountBudgetProposalErrorEnum",}, +) + + +class AccountBudgetProposalErrorEnum(proto.Message): + r"""Container for enum describing possible account budget + proposal errors. + + """ + + class AccountBudgetProposalError(proto.Enum): + r"""Enum describing possible account budget proposal errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FIELD_MASK_NOT_ALLOWED = 2 + IMMUTABLE_FIELD = 3 + REQUIRED_FIELD_MISSING = 4 + CANNOT_CANCEL_APPROVED_PROPOSAL = 5 + CANNOT_REMOVE_UNAPPROVED_BUDGET = 6 + CANNOT_REMOVE_RUNNING_BUDGET = 7 + CANNOT_END_UNAPPROVED_BUDGET = 8 + CANNOT_END_INACTIVE_BUDGET = 9 + BUDGET_NAME_REQUIRED = 10 + CANNOT_UPDATE_OLD_BUDGET = 11 + CANNOT_END_IN_PAST = 12 + CANNOT_EXTEND_END_TIME = 13 + PURCHASE_ORDER_NUMBER_REQUIRED = 14 + PENDING_UPDATE_PROPOSAL_EXISTS = 15 + MULTIPLE_BUDGETS_NOT_ALLOWED_FOR_UNAPPROVED_BILLING_SETUP = 16 + CANNOT_UPDATE_START_TIME_FOR_STARTED_BUDGET = 17 + SPENDING_LIMIT_LOWER_THAN_ACCRUED_COST_NOT_ALLOWED = 18 + UPDATE_IS_NO_OP = 19 + END_TIME_MUST_FOLLOW_START_TIME = 20 + BUDGET_DATE_RANGE_INCOMPATIBLE_WITH_BILLING_SETUP = 21 + NOT_AUTHORIZED = 22 + INVALID_BILLING_SETUP = 23 + OVERLAPS_EXISTING_BUDGET = 24 + CANNOT_CREATE_BUDGET_THROUGH_API = 25 + INVALID_MASTER_SERVICE_AGREEMENT = 26 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/account_link_error.py b/google/ads/googleads/v12/errors/types/account_link_error.py new file mode 100644 index 000000000..40ca881f6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/account_link_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AccountLinkErrorEnum",}, +) + + +class AccountLinkErrorEnum(proto.Message): + r"""Container for enum describing possible account link errors. + """ + + class AccountLinkError(proto.Enum): + r"""Enum describing possible account link errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_STATUS = 2 + PERMISSION_DENIED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_customizer_error.py b/google/ads/googleads/v12/errors/types/ad_customizer_error.py new file mode 100644 index 000000000..3e56c4b3d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_customizer_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdCustomizerErrorEnum",}, +) + + +class AdCustomizerErrorEnum(proto.Message): + r"""Container for enum describing possible ad customizer errors. + """ + + class AdCustomizerError(proto.Enum): + r"""Enum describing possible ad customizer errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + COUNTDOWN_INVALID_DATE_FORMAT = 2 + COUNTDOWN_DATE_IN_PAST = 3 + COUNTDOWN_INVALID_LOCALE = 4 + COUNTDOWN_INVALID_START_DAYS_BEFORE = 5 + UNKNOWN_USER_LIST = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_error.py b/google/ads/googleads/v12/errors/types/ad_error.py new file mode 100644 index 000000000..c7e6112f9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_error.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdErrorEnum",}, +) + + +class AdErrorEnum(proto.Message): + r"""Container for enum describing possible ad errors. + """ + + class AdError(proto.Enum): + r"""Enum describing possible ad errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_CUSTOMIZERS_NOT_SUPPORTED_FOR_AD_TYPE = 2 + APPROXIMATELY_TOO_LONG = 3 + APPROXIMATELY_TOO_SHORT = 4 + BAD_SNIPPET = 5 + CANNOT_MODIFY_AD = 6 + CANNOT_SET_BUSINESS_NAME_IF_URL_SET = 7 + CANNOT_SET_FIELD = 8 + CANNOT_SET_FIELD_WITH_ORIGIN_AD_ID_SET = 9 + CANNOT_SET_FIELD_WITH_AD_ID_SET_FOR_SHARING = 10 + CANNOT_SET_ALLOW_FLEXIBLE_COLOR_FALSE = 11 + CANNOT_SET_COLOR_CONTROL_WHEN_NATIVE_FORMAT_SETTING = 12 + CANNOT_SET_URL = 13 + CANNOT_SET_WITHOUT_FINAL_URLS = 14 + CANNOT_SET_WITH_FINAL_URLS = 15 + CANNOT_SET_WITH_URL_DATA = 17 + CANNOT_USE_AD_SUBCLASS_FOR_OPERATOR = 18 + CUSTOMER_NOT_APPROVED_MOBILEADS = 19 + CUSTOMER_NOT_APPROVED_THIRDPARTY_ADS = 20 + CUSTOMER_NOT_APPROVED_THIRDPARTY_REDIRECT_ADS = 21 + CUSTOMER_NOT_ELIGIBLE = 22 + CUSTOMER_NOT_ELIGIBLE_FOR_UPDATING_BEACON_URL = 23 + DIMENSION_ALREADY_IN_UNION = 24 + DIMENSION_MUST_BE_SET = 25 + DIMENSION_NOT_IN_UNION = 26 + DISPLAY_URL_CANNOT_BE_SPECIFIED = 27 + DOMESTIC_PHONE_NUMBER_FORMAT = 28 + EMERGENCY_PHONE_NUMBER = 29 + EMPTY_FIELD = 30 + FEED_ATTRIBUTE_MUST_HAVE_MAPPING_FOR_TYPE_ID = 31 + FEED_ATTRIBUTE_MAPPING_TYPE_MISMATCH = 32 + ILLEGAL_AD_CUSTOMIZER_TAG_USE = 33 + ILLEGAL_TAG_USE = 34 + INCONSISTENT_DIMENSIONS = 35 + INCONSISTENT_STATUS_IN_TEMPLATE_UNION = 36 + INCORRECT_LENGTH = 37 + INELIGIBLE_FOR_UPGRADE = 38 + INVALID_AD_ADDRESS_CAMPAIGN_TARGET = 39 + INVALID_AD_TYPE = 40 + INVALID_ATTRIBUTES_FOR_MOBILE_IMAGE = 41 + INVALID_ATTRIBUTES_FOR_MOBILE_TEXT = 42 + INVALID_CALL_TO_ACTION_TEXT = 43 + INVALID_CHARACTER_FOR_URL = 44 + INVALID_COUNTRY_CODE = 45 + INVALID_EXPANDED_DYNAMIC_SEARCH_AD_TAG = 47 + INVALID_INPUT = 48 + INVALID_MARKUP_LANGUAGE = 49 + INVALID_MOBILE_CARRIER = 50 + INVALID_MOBILE_CARRIER_TARGET = 51 + INVALID_NUMBER_OF_ELEMENTS = 52 + INVALID_PHONE_NUMBER_FORMAT = 53 + INVALID_RICH_MEDIA_CERTIFIED_VENDOR_FORMAT_ID = 54 + INVALID_TEMPLATE_DATA = 55 + INVALID_TEMPLATE_ELEMENT_FIELD_TYPE = 56 + INVALID_TEMPLATE_ID = 57 + LINE_TOO_WIDE = 58 + MISSING_AD_CUSTOMIZER_MAPPING = 59 + MISSING_ADDRESS_COMPONENT = 60 + MISSING_ADVERTISEMENT_NAME = 61 + MISSING_BUSINESS_NAME = 62 + MISSING_DESCRIPTION1 = 63 + MISSING_DESCRIPTION2 = 64 + MISSING_DESTINATION_URL_TAG = 65 + MISSING_LANDING_PAGE_URL_TAG = 66 + MISSING_DIMENSION = 67 + MISSING_DISPLAY_URL = 68 + MISSING_HEADLINE = 69 + MISSING_HEIGHT = 70 + MISSING_IMAGE = 71 + MISSING_MARKETING_IMAGE_OR_PRODUCT_VIDEOS = 72 + MISSING_MARKUP_LANGUAGES = 73 + MISSING_MOBILE_CARRIER = 74 + MISSING_PHONE = 75 + MISSING_REQUIRED_TEMPLATE_FIELDS = 76 + MISSING_TEMPLATE_FIELD_VALUE = 77 + MISSING_TEXT = 78 + MISSING_VISIBLE_URL = 79 + MISSING_WIDTH = 80 + MULTIPLE_DISTINCT_FEEDS_UNSUPPORTED = 81 + MUST_USE_TEMP_AD_UNION_ID_ON_ADD = 82 + TOO_LONG = 83 + TOO_SHORT = 84 + UNION_DIMENSIONS_CANNOT_CHANGE = 85 + UNKNOWN_ADDRESS_COMPONENT = 86 + UNKNOWN_FIELD_NAME = 87 + UNKNOWN_UNIQUE_NAME = 88 + UNSUPPORTED_DIMENSIONS = 89 + URL_INVALID_SCHEME = 90 + URL_INVALID_TOP_LEVEL_DOMAIN = 91 + URL_MALFORMED = 92 + URL_NO_HOST = 93 + URL_NOT_EQUIVALENT = 94 + URL_HOST_NAME_TOO_LONG = 95 + URL_NO_SCHEME = 96 + URL_NO_TOP_LEVEL_DOMAIN = 97 + URL_PATH_NOT_ALLOWED = 98 + URL_PORT_NOT_ALLOWED = 99 + URL_QUERY_NOT_ALLOWED = 100 + URL_SCHEME_BEFORE_EXPANDED_DYNAMIC_SEARCH_AD_TAG = 102 + USER_DOES_NOT_HAVE_ACCESS_TO_TEMPLATE = 103 + INCONSISTENT_EXPANDABLE_SETTINGS = 104 + INVALID_FORMAT = 105 + INVALID_FIELD_TEXT = 106 + ELEMENT_NOT_PRESENT = 107 + IMAGE_ERROR = 108 + VALUE_NOT_IN_RANGE = 109 + FIELD_NOT_PRESENT = 110 + ADDRESS_NOT_COMPLETE = 111 + ADDRESS_INVALID = 112 + VIDEO_RETRIEVAL_ERROR = 113 + AUDIO_ERROR = 114 + INVALID_YOUTUBE_DISPLAY_URL = 115 + TOO_MANY_PRODUCT_IMAGES = 116 + TOO_MANY_PRODUCT_VIDEOS = 117 + INCOMPATIBLE_AD_TYPE_AND_DEVICE_PREFERENCE = 118 + CALLTRACKING_NOT_SUPPORTED_FOR_COUNTRY = 119 + CARRIER_SPECIFIC_SHORT_NUMBER_NOT_ALLOWED = 120 + DISALLOWED_NUMBER_TYPE = 121 + PHONE_NUMBER_NOT_SUPPORTED_FOR_COUNTRY = 122 + PHONE_NUMBER_NOT_SUPPORTED_WITH_CALLTRACKING_FOR_COUNTRY = 123 + PREMIUM_RATE_NUMBER_NOT_ALLOWED = 124 + VANITY_PHONE_NUMBER_NOT_ALLOWED = 125 + INVALID_CALL_CONVERSION_TYPE_ID = 126 + CANNOT_DISABLE_CALL_CONVERSION_AND_SET_CONVERSION_TYPE_ID = 127 + CANNOT_SET_PATH2_WITHOUT_PATH1 = 128 + MISSING_DYNAMIC_SEARCH_ADS_SETTING_DOMAIN_NAME = 129 + INCOMPATIBLE_WITH_RESTRICTION_TYPE = 130 + CUSTOMER_CONSENT_FOR_CALL_RECORDING_REQUIRED = 131 + MISSING_IMAGE_OR_MEDIA_BUNDLE = 132 + PRODUCT_TYPE_NOT_SUPPORTED_IN_THIS_CAMPAIGN = 133 + PLACEHOLDER_CANNOT_HAVE_EMPTY_DEFAULT_VALUE = 134 + PLACEHOLDER_COUNTDOWN_FUNCTION_CANNOT_HAVE_DEFAULT_VALUE = 135 + PLACEHOLDER_DEFAULT_VALUE_MISSING = 136 + UNEXPECTED_PLACEHOLDER_DEFAULT_VALUE = 137 + AD_CUSTOMIZERS_MAY_NOT_BE_ADJACENT = 138 + UPDATING_AD_WITH_NO_ENABLED_ASSOCIATION = 139 + CALL_AD_VERIFICATION_URL_FINAL_URL_DOES_NOT_HAVE_SAME_DOMAIN = 140 + CALL_AD_FINAL_URL_AND_VERIFICATION_URL_CANNOT_BOTH_BE_EMPTY = 154 + TOO_MANY_AD_CUSTOMIZERS = 141 + INVALID_AD_CUSTOMIZER_FORMAT = 142 + NESTED_AD_CUSTOMIZER_SYNTAX = 143 + UNSUPPORTED_AD_CUSTOMIZER_SYNTAX = 144 + UNPAIRED_BRACE_IN_AD_CUSTOMIZER_TAG = 145 + MORE_THAN_ONE_COUNTDOWN_TAG_TYPE_EXISTS = 146 + DATE_TIME_IN_COUNTDOWN_TAG_IS_INVALID = 147 + DATE_TIME_IN_COUNTDOWN_TAG_IS_PAST = 148 + UNRECOGNIZED_AD_CUSTOMIZER_TAG_FOUND = 149 + CUSTOMIZER_TYPE_FORBIDDEN_FOR_FIELD = 150 + INVALID_CUSTOMIZER_ATTRIBUTE_NAME = 151 + STORE_MISMATCH = 152 + MISSING_REQUIRED_IMAGE_ASPECT_RATIO = 153 + MISMATCHED_ASPECT_RATIOS = 155 + DUPLICATE_IMAGE_ACROSS_CAROUSEL_CARDS = 156 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_ad_error.py b/google/ads/googleads/v12/errors/types/ad_group_ad_error.py new file mode 100644 index 000000000..bd6d82d49 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_ad_error.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdErrorEnum",}, +) + + +class AdGroupAdErrorEnum(proto.Message): + r"""Container for enum describing possible ad group ad errors. + """ + + class AdGroupAdError(proto.Enum): + r"""Enum describing possible ad group ad errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP_AD_LABEL_DOES_NOT_EXIST = 2 + AD_GROUP_AD_LABEL_ALREADY_EXISTS = 3 + AD_NOT_UNDER_ADGROUP = 4 + CANNOT_OPERATE_ON_REMOVED_ADGROUPAD = 5 + CANNOT_CREATE_DEPRECATED_ADS = 6 + CANNOT_CREATE_TEXT_ADS = 7 + EMPTY_FIELD = 8 + RESOURCE_REFERENCED_IN_MULTIPLE_OPS = 9 + AD_TYPE_CANNOT_BE_PAUSED = 10 + AD_TYPE_CANNOT_BE_REMOVED = 11 + CANNOT_UPDATE_DEPRECATED_ADS = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_bid_modifier_error.py b/google/ads/googleads/v12/errors/types/ad_group_bid_modifier_error.py new file mode 100644 index 000000000..1566b197a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_bid_modifier_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupBidModifierErrorEnum",}, +) + + +class AdGroupBidModifierErrorEnum(proto.Message): + r"""Container for enum describing possible ad group bid modifier + errors. + + """ + + class AdGroupBidModifierError(proto.Enum): + r"""Enum describing possible ad group bid modifier errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CRITERION_ID_NOT_SUPPORTED = 2 + CANNOT_OVERRIDE_OPTED_OUT_CAMPAIGN_CRITERION_BID_MODIFIER = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_criterion_customizer_error.py b/google/ads/googleads/v12/errors/types/ad_group_criterion_customizer_error.py new file mode 100644 index 000000000..1feb3b162 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_criterion_customizer_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionCustomizerErrorEnum",}, +) + + +class AdGroupCriterionCustomizerErrorEnum(proto.Message): + r"""Container for enum describing possible ad group criterion + customizer errors. + + """ + + class AdGroupCriterionCustomizerError(proto.Enum): + r"""Enum describing possible ad group criterion customizer + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CRITERION_IS_NOT_KEYWORD = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_criterion_error.py b/google/ads/googleads/v12/errors/types/ad_group_criterion_error.py new file mode 100644 index 000000000..41f39887e --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_criterion_error.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionErrorEnum",}, +) + + +class AdGroupCriterionErrorEnum(proto.Message): + r"""Container for enum describing possible ad group criterion + errors. + + """ + + class AdGroupCriterionError(proto.Enum): + r"""Enum describing possible ad group criterion errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP_CRITERION_LABEL_DOES_NOT_EXIST = 2 + AD_GROUP_CRITERION_LABEL_ALREADY_EXISTS = 3 + CANNOT_ADD_LABEL_TO_NEGATIVE_CRITERION = 4 + TOO_MANY_OPERATIONS = 5 + CANT_UPDATE_NEGATIVE = 6 + CONCRETE_TYPE_REQUIRED = 7 + BID_INCOMPATIBLE_WITH_ADGROUP = 8 + CANNOT_TARGET_AND_EXCLUDE = 9 + ILLEGAL_URL = 10 + INVALID_KEYWORD_TEXT = 11 + INVALID_DESTINATION_URL = 12 + MISSING_DESTINATION_URL_TAG = 13 + KEYWORD_LEVEL_BID_NOT_SUPPORTED_FOR_MANUALCPM = 14 + INVALID_USER_STATUS = 15 + CANNOT_ADD_CRITERIA_TYPE = 16 + CANNOT_EXCLUDE_CRITERIA_TYPE = 17 + CAMPAIGN_TYPE_NOT_COMPATIBLE_WITH_PARTIAL_FAILURE = 27 + OPERATIONS_FOR_TOO_MANY_SHOPPING_ADGROUPS = 28 + CANNOT_MODIFY_URL_FIELDS_WITH_DUPLICATE_ELEMENTS = 29 + CANNOT_SET_WITHOUT_FINAL_URLS = 30 + CANNOT_CLEAR_FINAL_URLS_IF_FINAL_MOBILE_URLS_EXIST = 31 + CANNOT_CLEAR_FINAL_URLS_IF_FINAL_APP_URLS_EXIST = 32 + CANNOT_CLEAR_FINAL_URLS_IF_TRACKING_URL_TEMPLATE_EXISTS = 33 + CANNOT_CLEAR_FINAL_URLS_IF_URL_CUSTOM_PARAMETERS_EXIST = 34 + CANNOT_SET_BOTH_DESTINATION_URL_AND_FINAL_URLS = 35 + CANNOT_SET_BOTH_DESTINATION_URL_AND_TRACKING_URL_TEMPLATE = 36 + FINAL_URLS_NOT_SUPPORTED_FOR_CRITERION_TYPE = 37 + FINAL_MOBILE_URLS_NOT_SUPPORTED_FOR_CRITERION_TYPE = 38 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_customizer_error.py b/google/ads/googleads/v12/errors/types/ad_group_customizer_error.py new file mode 100644 index 000000000..cf051fdbc --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_customizer_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCustomizerErrorEnum",}, +) + + +class AdGroupCustomizerErrorEnum(proto.Message): + r"""Container for enum describing possible ad group customizer + errors. + + """ + + class AdGroupCustomizerError(proto.Enum): + r"""Enum describing possible ad group customizer errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_error.py b/google/ads/googleads/v12/errors/types/ad_group_error.py new file mode 100644 index 000000000..f1e9f64e1 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_error.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupErrorEnum",}, +) + + +class AdGroupErrorEnum(proto.Message): + r"""Container for enum describing possible ad group errors. + """ + + class AdGroupError(proto.Enum): + r"""Enum describing possible ad group errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_ADGROUP_NAME = 2 + INVALID_ADGROUP_NAME = 3 + ADVERTISER_NOT_ON_CONTENT_NETWORK = 5 + BID_TOO_BIG = 6 + BID_TYPE_AND_BIDDING_STRATEGY_MISMATCH = 7 + MISSING_ADGROUP_NAME = 8 + ADGROUP_LABEL_DOES_NOT_EXIST = 9 + ADGROUP_LABEL_ALREADY_EXISTS = 10 + INVALID_CONTENT_BID_CRITERION_TYPE_GROUP = 11 + AD_GROUP_TYPE_NOT_VALID_FOR_ADVERTISING_CHANNEL_TYPE = 12 + ADGROUP_TYPE_NOT_SUPPORTED_FOR_CAMPAIGN_SALES_COUNTRY = 13 + CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING = 14 + PROMOTED_HOTEL_AD_GROUPS_NOT_AVAILABLE_FOR_CUSTOMER = 15 + INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE = 16 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_group_feed_error.py b/google/ads/googleads/v12/errors/types/ad_group_feed_error.py new file mode 100644 index 000000000..3c98bf1ca --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_group_feed_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdGroupFeedErrorEnum",}, +) + + +class AdGroupFeedErrorEnum(proto.Message): + r"""Container for enum describing possible ad group feed errors. + """ + + class AdGroupFeedError(proto.Enum): + r"""Enum describing possible ad group feed errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 2 + CANNOT_CREATE_FOR_REMOVED_FEED = 3 + ADGROUP_FEED_ALREADY_EXISTS = 4 + CANNOT_OPERATE_ON_REMOVED_ADGROUP_FEED = 5 + INVALID_PLACEHOLDER_TYPE = 6 + MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE = 7 + NO_EXISTING_LOCATION_CUSTOMER_FEED = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_parameter_error.py b/google/ads/googleads/v12/errors/types/ad_parameter_error.py new file mode 100644 index 000000000..c6a6e8139 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_parameter_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdParameterErrorEnum",}, +) + + +class AdParameterErrorEnum(proto.Message): + r"""Container for enum describing possible ad parameter errors. + """ + + class AdParameterError(proto.Enum): + r"""Enum describing possible ad parameter errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP_CRITERION_MUST_BE_KEYWORD = 2 + INVALID_INSERTION_TEXT_FORMAT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/ad_sharing_error.py b/google/ads/googleads/v12/errors/types/ad_sharing_error.py new file mode 100644 index 000000000..6c0ea9bbf --- /dev/null +++ b/google/ads/googleads/v12/errors/types/ad_sharing_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdSharingErrorEnum",}, +) + + +class AdSharingErrorEnum(proto.Message): + r"""Container for enum describing possible ad sharing errors. + """ + + class AdSharingError(proto.Enum): + r"""Enum describing possible ad sharing errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AD_GROUP_ALREADY_CONTAINS_AD = 2 + INCOMPATIBLE_AD_UNDER_AD_GROUP = 3 + CANNOT_SHARE_INACTIVE_AD = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/adx_error.py b/google/ads/googleads/v12/errors/types/adx_error.py new file mode 100644 index 000000000..aab9cc20b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/adx_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AdxErrorEnum",}, +) + + +class AdxErrorEnum(proto.Message): + r"""Container for enum describing possible adx errors. + """ + + class AdxError(proto.Enum): + r"""Enum describing possible adx errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNSUPPORTED_FEATURE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_error.py b/google/ads/googleads/v12/errors/types/asset_error.py new file mode 100644 index 000000000..92dd24aba --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_error.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetErrorEnum",}, +) + + +class AssetErrorEnum(proto.Message): + r"""Container for enum describing possible asset errors. + """ + + class AssetError(proto.Enum): + r"""Enum describing possible asset errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER_NOT_ON_ALLOWLIST_FOR_ASSET_TYPE = 13 + DUPLICATE_ASSET = 3 + DUPLICATE_ASSET_NAME = 4 + ASSET_DATA_IS_MISSING = 5 + CANNOT_MODIFY_ASSET_NAME = 6 + FIELD_INCOMPATIBLE_WITH_ASSET_TYPE = 7 + INVALID_CALL_TO_ACTION_TEXT = 8 + LEAD_FORM_INVALID_FIELDS_COMBINATION = 9 + LEAD_FORM_MISSING_AGREEMENT = 10 + INVALID_ASSET_STATUS = 11 + FIELD_CANNOT_BE_MODIFIED_FOR_ASSET_TYPE = 12 + SCHEDULES_CANNOT_OVERLAP = 14 + PROMOTION_CANNOT_SET_PERCENT_OFF_AND_MONEY_AMOUNT_OFF = 15 + PROMOTION_CANNOT_SET_PROMOTION_CODE_AND_ORDERS_OVER_AMOUNT = 16 + TOO_MANY_DECIMAL_PLACES_SPECIFIED = 17 + DUPLICATE_ASSETS_WITH_DIFFERENT_FIELD_VALUE = 18 + CALL_CARRIER_SPECIFIC_SHORT_NUMBER_NOT_ALLOWED = 19 + CALL_CUSTOMER_CONSENT_FOR_CALL_RECORDING_REQUIRED = 20 + CALL_DISALLOWED_NUMBER_TYPE = 21 + CALL_INVALID_CONVERSION_ACTION = 22 + CALL_INVALID_COUNTRY_CODE = 23 + CALL_INVALID_DOMESTIC_PHONE_NUMBER_FORMAT = 24 + CALL_INVALID_PHONE_NUMBER = 25 + CALL_PHONE_NUMBER_NOT_SUPPORTED_FOR_COUNTRY = 26 + CALL_PREMIUM_RATE_NUMBER_NOT_ALLOWED = 27 + CALL_VANITY_PHONE_NUMBER_NOT_ALLOWED = 28 + PRICE_HEADER_SAME_AS_DESCRIPTION = 29 + MOBILE_APP_INVALID_APP_ID = 30 + MOBILE_APP_INVALID_FINAL_URL_FOR_APP_DOWNLOAD_URL = 31 + NAME_REQUIRED_FOR_ASSET_TYPE = 32 + LEAD_FORM_LEGACY_QUALIFYING_QUESTIONS_DISALLOWED = 33 + NAME_CONFLICT_FOR_ASSET_TYPE = 34 + CANNOT_MODIFY_ASSET_SOURCE = 35 + CANNOT_MODIFY_AUTOMATICALLY_CREATED_ASSET = 36 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_group_asset_error.py b/google/ads/googleads/v12/errors/types/asset_group_asset_error.py new file mode 100644 index 000000000..db4e06e6d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_group_asset_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupAssetErrorEnum",}, +) + + +class AssetGroupAssetErrorEnum(proto.Message): + r"""Container for enum describing possible asset group asset + errors. + + """ + + class AssetGroupAssetError(proto.Enum): + r"""Enum describing possible asset group asset errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_RESOURCE = 2 + EXPANDABLE_TAGS_NOT_ALLOWED_IN_DESCRIPTION = 3 + AD_CUSTOMIZER_NOT_SUPPORTED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_group_error.py b/google/ads/googleads/v12/errors/types/asset_group_error.py new file mode 100644 index 000000000..24636f716 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_group_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupErrorEnum",}, +) + + +class AssetGroupErrorEnum(proto.Message): + r"""Container for enum describing possible asset group errors. + """ + + class AssetGroupError(proto.Enum): + r"""Enum describing possible asset group errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_NAME = 2 + CANNOT_ADD_ASSET_GROUP_FOR_CAMPAIGN_TYPE = 3 + NOT_ENOUGH_HEADLINE_ASSET = 4 + NOT_ENOUGH_LONG_HEADLINE_ASSET = 5 + NOT_ENOUGH_DESCRIPTION_ASSET = 6 + NOT_ENOUGH_BUSINESS_NAME_ASSET = 7 + NOT_ENOUGH_MARKETING_IMAGE_ASSET = 8 + NOT_ENOUGH_SQUARE_MARKETING_IMAGE_ASSET = 9 + NOT_ENOUGH_LOGO_ASSET = 10 + FINAL_URL_SHOPPING_MERCHANT_HOME_PAGE_URL_DOMAINS_DIFFER = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_group_listing_group_filter_error.py b/google/ads/googleads/v12/errors/types/asset_group_listing_group_filter_error.py new file mode 100644 index 000000000..e229fd031 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_group_listing_group_filter_error.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupListingGroupFilterErrorEnum",}, +) + + +class AssetGroupListingGroupFilterErrorEnum(proto.Message): + r"""Container for enum describing possible asset group listing + group filter errors. + + """ + + class AssetGroupListingGroupFilterError(proto.Enum): + r"""Enum describing possible asset group listing group filter + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + TREE_TOO_DEEP = 2 + UNIT_CANNOT_HAVE_CHILDREN = 3 + SUBDIVISION_MUST_HAVE_EVERYTHING_ELSE_CHILD = 4 + DIFFERENT_DIMENSION_TYPE_BETWEEN_SIBLINGS = 5 + SAME_DIMENSION_VALUE_BETWEEN_SIBLINGS = 6 + SAME_DIMENSION_TYPE_BETWEEN_ANCESTORS = 7 + MULTIPLE_ROOTS = 8 + INVALID_DIMENSION_VALUE = 9 + MUST_REFINE_HIERARCHICAL_PARENT_TYPE = 10 + INVALID_PRODUCT_BIDDING_CATEGORY = 11 + CHANGING_CASE_VALUE_WITH_CHILDREN = 12 + SUBDIVISION_HAS_CHILDREN = 13 + CANNOT_REFINE_HIERARCHICAL_EVERYTHING_ELSE = 14 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_link_error.py b/google/ads/googleads/v12/errors/types/asset_link_error.py new file mode 100644 index 000000000..121c37a99 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_link_error.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetLinkErrorEnum",}, +) + + +class AssetLinkErrorEnum(proto.Message): + r"""Container for enum describing possible asset link errors. + """ + + class AssetLinkError(proto.Enum): + r"""Enum describing possible asset link errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PINNING_UNSUPPORTED = 2 + UNSUPPORTED_FIELD_TYPE = 3 + FIELD_TYPE_INCOMPATIBLE_WITH_ASSET_TYPE = 4 + FIELD_TYPE_INCOMPATIBLE_WITH_CAMPAIGN_TYPE = 5 + INCOMPATIBLE_ADVERTISING_CHANNEL_TYPE = 6 + IMAGE_NOT_WITHIN_SPECIFIED_DIMENSION_RANGE = 7 + INVALID_PINNED_FIELD = 8 + MEDIA_BUNDLE_ASSET_FILE_SIZE_TOO_LARGE = 9 + NOT_ENOUGH_AVAILABLE_ASSET_LINKS_FOR_VALID_COMBINATION = 10 + NOT_ENOUGH_AVAILABLE_ASSET_LINKS_WITH_FALLBACK = 11 + NOT_ENOUGH_AVAILABLE_ASSET_LINKS_WITH_FALLBACK_FOR_VALID_COMBINATION = ( + 12 + ) + YOUTUBE_VIDEO_REMOVED = 13 + YOUTUBE_VIDEO_TOO_LONG = 14 + YOUTUBE_VIDEO_TOO_SHORT = 15 + EXCLUDED_PARENT_FIELD_TYPE = 16 + INVALID_STATUS = 17 + YOUTUBE_VIDEO_DURATION_NOT_DEFINED = 18 + CANNOT_CREATE_AUTOMATICALLY_CREATED_LINKS = 19 + CANNOT_LINK_TO_AUTOMATICALLY_CREATED_ASSET = 20 + CANNOT_MODIFY_ASSET_LINK_SOURCE = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_set_asset_error.py b/google/ads/googleads/v12/errors/types/asset_set_asset_error.py new file mode 100644 index 000000000..58f9287f4 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_set_asset_error.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetSetAssetErrorEnum",}, +) + + +class AssetSetAssetErrorEnum(proto.Message): + r"""Container for enum describing possible asset set asset + errors. + + """ + + class AssetSetAssetError(proto.Enum): + r"""Enum describing possible asset set asset errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_ASSET_TYPE = 2 + INVALID_ASSET_SET_TYPE = 3 + DUPLICATE_EXTERNAL_KEY = 4 + PARENT_LINKAGE_DOES_NOT_EXIST = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_set_error.py b/google/ads/googleads/v12/errors/types/asset_set_error.py new file mode 100644 index 000000000..09620ac9d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_set_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetSetErrorEnum",}, +) + + +class AssetSetErrorEnum(proto.Message): + r"""Container for enum describing possible asset set errors. + """ + + class AssetSetError(proto.Enum): + r"""Enum describing possible asset set errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_ASSET_SET_NAME = 2 + INVALID_PARENT_ASSET_SET_TYPE = 3 + ASSET_SET_SOURCE_INCOMPATIBLE_WITH_PARENT_ASSET_SET = 4 + ASSET_SET_TYPE_CANNOT_BE_LINKED_TO_CUSTOMER = 5 + INVALID_CHAIN_IDS = 6 + LOCATION_SYNC_ASSET_SET_DOES_NOT_SUPPORT_RELATIONSHIP_TYPE = 7 + NOT_UNIQUE_ENABLED_LOCATION_SYNC_TYPED_ASSET_SET = 8 + INVALID_PLACE_IDS = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/asset_set_link_error.py b/google/ads/googleads/v12/errors/types/asset_set_link_error.py new file mode 100644 index 000000000..e48d9bdac --- /dev/null +++ b/google/ads/googleads/v12/errors/types/asset_set_link_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AssetSetLinkErrorEnum",}, +) + + +class AssetSetLinkErrorEnum(proto.Message): + r"""Container for enum describing possible asset set link errors. + """ + + class AssetSetLinkError(proto.Enum): + r"""Enum describing possible asset set link errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INCOMPATIBLE_ADVERTISING_CHANNEL_TYPE = 2 + DUPLICATE_FEED_LINK = 3 + INCOMPATIBLE_ASSET_SET_TYPE_WITH_CAMPAIGN_TYPE = 4 + DUPLICATE_ASSET_SET_LINK = 5 + ASSET_SET_LINK_CANNOT_BE_REMOVED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/audience_error.py b/google/ads/googleads/v12/errors/types/audience_error.py new file mode 100644 index 000000000..195982876 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/audience_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AudienceErrorEnum",}, +) + + +class AudienceErrorEnum(proto.Message): + r"""Container for enum describing possible audience errors. + """ + + class AudienceError(proto.Enum): + r"""Enum describing possible audience errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NAME_ALREADY_IN_USE = 2 + DIMENSION_INVALID = 3 + AUDIENCE_SEGMENT_NOT_FOUND = 4 + AUDIENCE_SEGMENT_TYPE_NOT_SUPPORTED = 5 + DUPLICATE_AUDIENCE_SEGMENT = 6 + TOO_MANY_SEGMENTS = 7 + TOO_MANY_DIMENSIONS_OF_SAME_TYPE = 8 + IN_USE = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/audience_insights_error.py b/google/ads/googleads/v12/errors/types/audience_insights_error.py new file mode 100644 index 000000000..c6a6bb531 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/audience_insights_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AudienceInsightsErrorEnum",}, +) + + +class AudienceInsightsErrorEnum(proto.Message): + r"""Container for enum describing possible errors returned from + the AudienceInsightsService. + + """ + + class AudienceInsightsError(proto.Enum): + r"""Enum describing possible errors from AudienceInsightsService.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DIMENSION_INCOMPATIBLE_WITH_TOPIC_AUDIENCE_COMBINATIONS = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/authentication_error.py b/google/ads/googleads/v12/errors/types/authentication_error.py new file mode 100644 index 000000000..e564a87e0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/authentication_error.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AuthenticationErrorEnum",}, +) + + +class AuthenticationErrorEnum(proto.Message): + r"""Container for enum describing possible authentication errors. + """ + + class AuthenticationError(proto.Enum): + r"""Enum describing possible authentication errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + AUTHENTICATION_ERROR = 2 + CLIENT_CUSTOMER_ID_INVALID = 5 + CUSTOMER_NOT_FOUND = 8 + GOOGLE_ACCOUNT_DELETED = 9 + GOOGLE_ACCOUNT_COOKIE_INVALID = 10 + GOOGLE_ACCOUNT_AUTHENTICATION_FAILED = 25 + GOOGLE_ACCOUNT_USER_AND_ADS_USER_MISMATCH = 12 + LOGIN_COOKIE_REQUIRED = 13 + NOT_ADS_USER = 14 + OAUTH_TOKEN_INVALID = 15 + OAUTH_TOKEN_EXPIRED = 16 + OAUTH_TOKEN_DISABLED = 17 + OAUTH_TOKEN_REVOKED = 18 + OAUTH_TOKEN_HEADER_INVALID = 19 + LOGIN_COOKIE_INVALID = 20 + USER_ID_INVALID = 22 + TWO_STEP_VERIFICATION_NOT_ENROLLED = 23 + ADVANCED_PROTECTION_NOT_ENROLLED = 24 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/authorization_error.py b/google/ads/googleads/v12/errors/types/authorization_error.py new file mode 100644 index 000000000..40ef70f88 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/authorization_error.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"AuthorizationErrorEnum",}, +) + + +class AuthorizationErrorEnum(proto.Message): + r"""Container for enum describing possible authorization errors. + """ + + class AuthorizationError(proto.Enum): + r"""Enum describing possible authorization errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + USER_PERMISSION_DENIED = 2 + DEVELOPER_TOKEN_NOT_ON_ALLOWLIST = 13 + DEVELOPER_TOKEN_PROHIBITED = 4 + PROJECT_DISABLED = 5 + AUTHORIZATION_ERROR = 6 + ACTION_NOT_PERMITTED = 7 + INCOMPLETE_SIGNUP = 8 + CUSTOMER_NOT_ENABLED = 24 + MISSING_TOS = 9 + DEVELOPER_TOKEN_NOT_APPROVED = 10 + INVALID_LOGIN_CUSTOMER_ID_SERVING_CUSTOMER_ID_COMBINATION = 11 + SERVICE_ACCESS_DENIED = 12 + ACCESS_DENIED_FOR_ACCOUNT_TYPE = 25 + METRIC_ACCESS_DENIED = 26 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/batch_job_error.py b/google/ads/googleads/v12/errors/types/batch_job_error.py new file mode 100644 index 000000000..f3b09465b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/batch_job_error.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"BatchJobErrorEnum",}, +) + + +class BatchJobErrorEnum(proto.Message): + r"""Container for enum describing possible batch job errors. + """ + + class BatchJobError(proto.Enum): + r"""Enum describing possible request errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_MODIFY_JOB_AFTER_JOB_STARTS_RUNNING = 2 + EMPTY_OPERATIONS = 3 + INVALID_SEQUENCE_TOKEN = 4 + RESULTS_NOT_READY = 5 + INVALID_PAGE_SIZE = 6 + CAN_ONLY_REMOVE_PENDING_JOB = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/bidding_error.py b/google/ads/googleads/v12/errors/types/bidding_error.py new file mode 100644 index 000000000..eea5cab76 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/bidding_error.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"BiddingErrorEnum",}, +) + + +class BiddingErrorEnum(proto.Message): + r"""Container for enum describing possible bidding errors. + """ + + class BiddingError(proto.Enum): + r"""Enum describing possible bidding errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BIDDING_STRATEGY_TRANSITION_NOT_ALLOWED = 2 + CANNOT_ATTACH_BIDDING_STRATEGY_TO_CAMPAIGN = 7 + INVALID_ANONYMOUS_BIDDING_STRATEGY_TYPE = 10 + INVALID_BIDDING_STRATEGY_TYPE = 14 + INVALID_BID = 17 + BIDDING_STRATEGY_NOT_AVAILABLE_FOR_ACCOUNT_TYPE = 18 + CONVERSION_TRACKING_NOT_ENABLED = 19 + NOT_ENOUGH_CONVERSIONS = 20 + CANNOT_CREATE_CAMPAIGN_WITH_BIDDING_STRATEGY = 21 + CANNOT_TARGET_CONTENT_NETWORK_ONLY_WITH_CAMPAIGN_LEVEL_POP_BIDDING_STRATEGY = ( + 23 + ) + BIDDING_STRATEGY_NOT_SUPPORTED_WITH_AD_SCHEDULE = 24 + PAY_PER_CONVERSION_NOT_AVAILABLE_FOR_CUSTOMER = 25 + PAY_PER_CONVERSION_NOT_ALLOWED_WITH_TARGET_CPA = 26 + BIDDING_STRATEGY_NOT_ALLOWED_FOR_SEARCH_ONLY_CAMPAIGNS = 27 + BIDDING_STRATEGY_NOT_SUPPORTED_IN_DRAFTS_OR_EXPERIMENTS = 28 + BIDDING_STRATEGY_TYPE_DOES_NOT_SUPPORT_PRODUCT_TYPE_ADGROUP_CRITERION = ( + 29 + ) + BID_TOO_SMALL = 30 + BID_TOO_BIG = 31 + BID_TOO_MANY_FRACTIONAL_DIGITS = 32 + INVALID_DOMAIN_NAME = 33 + NOT_COMPATIBLE_WITH_PAYMENT_MODE = 34 + NOT_COMPATIBLE_WITH_BUDGET_TYPE = 35 + NOT_COMPATIBLE_WITH_BIDDING_STRATEGY_TYPE = 36 + BIDDING_STRATEGY_TYPE_INCOMPATIBLE_WITH_SHARED_BUDGET = 37 + BIDDING_STRATEGY_AND_BUDGET_MUST_BE_ALIGNED = 38 + BIDDING_STRATEGY_AND_BUDGET_MUST_BE_ATTACHED_TO_THE_SAME_CAMPAIGNS_TO_ALIGN = ( + 39 + ) + BIDDING_STRATEGY_AND_BUDGET_MUST_BE_REMOVED_TOGETHER = 40 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/bidding_strategy_error.py b/google/ads/googleads/v12/errors/types/bidding_strategy_error.py new file mode 100644 index 000000000..08d9fa464 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/bidding_strategy_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategyErrorEnum",}, +) + + +class BiddingStrategyErrorEnum(proto.Message): + r"""Container for enum describing possible bidding strategy + errors. + + """ + + class BiddingStrategyError(proto.Enum): + r"""Enum describing possible bidding strategy errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_NAME = 2 + CANNOT_CHANGE_BIDDING_STRATEGY_TYPE = 3 + CANNOT_REMOVE_ASSOCIATED_STRATEGY = 4 + BIDDING_STRATEGY_NOT_SUPPORTED = 5 + INCOMPATIBLE_BIDDING_STRATEGY_AND_BIDDING_STRATEGY_GOAL_TYPE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/billing_setup_error.py b/google/ads/googleads/v12/errors/types/billing_setup_error.py new file mode 100644 index 000000000..074e6c6f0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/billing_setup_error.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"BillingSetupErrorEnum",}, +) + + +class BillingSetupErrorEnum(proto.Message): + r"""Container for enum describing possible billing setup errors. + """ + + class BillingSetupError(proto.Enum): + r"""Enum describing possible billing setup errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_USE_EXISTING_AND_NEW_ACCOUNT = 2 + CANNOT_REMOVE_STARTED_BILLING_SETUP = 3 + CANNOT_CHANGE_BILLING_TO_SAME_PAYMENTS_ACCOUNT = 4 + BILLING_SETUP_NOT_PERMITTED_FOR_CUSTOMER_STATUS = 5 + INVALID_PAYMENTS_ACCOUNT = 6 + BILLING_SETUP_NOT_PERMITTED_FOR_CUSTOMER_CATEGORY = 7 + INVALID_START_TIME_TYPE = 8 + THIRD_PARTY_ALREADY_HAS_BILLING = 9 + BILLING_SETUP_IN_PROGRESS = 10 + NO_SIGNUP_PERMISSION = 11 + CHANGE_OF_BILL_TO_IN_PROGRESS = 12 + PAYMENTS_PROFILE_NOT_FOUND = 13 + PAYMENTS_ACCOUNT_NOT_FOUND = 14 + PAYMENTS_PROFILE_INELIGIBLE = 15 + PAYMENTS_ACCOUNT_INELIGIBLE = 16 + CUSTOMER_NEEDS_INTERNAL_APPROVAL = 17 + PAYMENTS_ACCOUNT_INELIGIBLE_CURRENCY_CODE_MISMATCH = 19 + FUTURE_START_TIME_PROHIBITED = 20 + TOO_MANY_BILLING_SETUPS_FOR_PAYMENTS_ACCOUNT = 21 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_budget_error.py b/google/ads/googleads/v12/errors/types/campaign_budget_error.py new file mode 100644 index 000000000..067c129a5 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_budget_error.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignBudgetErrorEnum",}, +) + + +class CampaignBudgetErrorEnum(proto.Message): + r"""Container for enum describing possible campaign budget + errors. + + """ + + class CampaignBudgetError(proto.Enum): + r"""Enum describing possible campaign budget errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN_BUDGET_CANNOT_BE_SHARED = 17 + CAMPAIGN_BUDGET_REMOVED = 2 + CAMPAIGN_BUDGET_IN_USE = 3 + CAMPAIGN_BUDGET_PERIOD_NOT_AVAILABLE = 4 + CANNOT_MODIFY_FIELD_OF_IMPLICITLY_SHARED_CAMPAIGN_BUDGET = 6 + CANNOT_UPDATE_CAMPAIGN_BUDGET_TO_IMPLICITLY_SHARED = 7 + CANNOT_UPDATE_CAMPAIGN_BUDGET_TO_EXPLICITLY_SHARED_WITHOUT_NAME = 8 + CANNOT_UPDATE_CAMPAIGN_BUDGET_TO_EXPLICITLY_SHARED = 9 + CANNOT_USE_IMPLICITLY_SHARED_CAMPAIGN_BUDGET_WITH_MULTIPLE_CAMPAIGNS = ( + 10 + ) + DUPLICATE_NAME = 11 + MONEY_AMOUNT_IN_WRONG_CURRENCY = 12 + MONEY_AMOUNT_LESS_THAN_CURRENCY_MINIMUM_CPC = 13 + MONEY_AMOUNT_TOO_LARGE = 14 + NEGATIVE_MONEY_AMOUNT = 15 + NON_MULTIPLE_OF_MINIMUM_CURRENCY_UNIT = 16 + TOTAL_BUDGET_AMOUNT_MUST_BE_UNSET_FOR_BUDGET_PERIOD_DAILY = 18 + INVALID_PERIOD = 19 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_conversion_goal_error.py b/google/ads/googleads/v12/errors/types/campaign_conversion_goal_error.py new file mode 100644 index 000000000..70f472ef6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_conversion_goal_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignConversionGoalErrorEnum",}, +) + + +class CampaignConversionGoalErrorEnum(proto.Message): + r"""Container for enum describing possible campaign conversion + goal errors. + + """ + + class CampaignConversionGoalError(proto.Enum): + r"""Enum describing possible campaign conversion goal errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_USE_CAMPAIGN_GOAL_FOR_SEARCH_ADS_360_MANAGED_CAMPAIGN = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_criterion_error.py b/google/ads/googleads/v12/errors/types/campaign_criterion_error.py new file mode 100644 index 000000000..c649874e0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_criterion_error.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignCriterionErrorEnum",}, +) + + +class CampaignCriterionErrorEnum(proto.Message): + r"""Container for enum describing possible campaign criterion + errors. + + """ + + class CampaignCriterionError(proto.Enum): + r"""Enum describing possible campaign criterion errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CONCRETE_TYPE_REQUIRED = 2 + INVALID_PLACEMENT_URL = 3 + CANNOT_EXCLUDE_CRITERIA_TYPE = 4 + CANNOT_SET_STATUS_FOR_CRITERIA_TYPE = 5 + CANNOT_SET_STATUS_FOR_EXCLUDED_CRITERIA = 6 + CANNOT_TARGET_AND_EXCLUDE = 7 + TOO_MANY_OPERATIONS = 8 + OPERATOR_NOT_SUPPORTED_FOR_CRITERION_TYPE = 9 + SHOPPING_CAMPAIGN_SALES_COUNTRY_NOT_SUPPORTED_FOR_SALES_CHANNEL = 10 + CANNOT_ADD_EXISTING_FIELD = 11 + CANNOT_UPDATE_NEGATIVE_CRITERION = 12 + CANNOT_SET_NEGATIVE_KEYWORD_THEME_CONSTANT_CRITERION = 13 + INVALID_KEYWORD_THEME_CONSTANT = 14 + MISSING_KEYWORD_THEME_CONSTANT_OR_FREE_FORM_KEYWORD_THEME = 15 + CANNOT_TARGET_BOTH_PROXIMITY_AND_LOCATION_CRITERIA_FOR_SMART_CAMPAIGN = ( + 16 + ) + CANNOT_TARGET_MULTIPLE_PROXIMITY_CRITERIA_FOR_SMART_CAMPAIGN = 17 + LOCATION_NOT_LAUNCHED_FOR_LOCAL_SERVICES_CAMPAIGN = 18 + LOCATION_INVALID_FOR_LOCAL_SERVICES_CAMPAIGN = 19 + CANNOT_TARGET_COUNTRY_FOR_LOCAL_SERVICES_CAMPAIGN = 20 + LOCATION_NOT_IN_HOME_COUNTRY_FOR_LOCAL_SERVICES_CAMPAIGN = 21 + CANNOT_ADD_OR_REMOVE_LOCATION_FOR_LOCAL_SERVICES_CAMPAIGN = 22 + AT_LEAST_ONE_POSITIVE_LOCATION_REQUIRED_FOR_LOCAL_SERVICES_CAMPAIGN = 23 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_customizer_error.py b/google/ads/googleads/v12/errors/types/campaign_customizer_error.py new file mode 100644 index 000000000..0784c8025 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_customizer_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignCustomizerErrorEnum",}, +) + + +class CampaignCustomizerErrorEnum(proto.Message): + r"""Container for enum describing possible campaign customizer + errors. + + """ + + class CampaignCustomizerError(proto.Enum): + r"""Enum describing possible campaign customizer errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_draft_error.py b/google/ads/googleads/v12/errors/types/campaign_draft_error.py new file mode 100644 index 000000000..f5421116b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_draft_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignDraftErrorEnum",}, +) + + +class CampaignDraftErrorEnum(proto.Message): + r"""Container for enum describing possible campaign draft errors. + """ + + class CampaignDraftError(proto.Enum): + r"""Enum describing possible campaign draft errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_DRAFT_NAME = 2 + INVALID_STATUS_TRANSITION_FROM_REMOVED = 3 + INVALID_STATUS_TRANSITION_FROM_PROMOTED = 4 + INVALID_STATUS_TRANSITION_FROM_PROMOTE_FAILED = 5 + CUSTOMER_CANNOT_CREATE_DRAFT = 6 + CAMPAIGN_CANNOT_CREATE_DRAFT = 7 + INVALID_DRAFT_CHANGE = 8 + INVALID_STATUS_TRANSITION = 9 + MAX_NUMBER_OF_DRAFTS_PER_CAMPAIGN_REACHED = 10 + LIST_ERRORS_FOR_PROMOTED_DRAFT_ONLY = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_error.py b/google/ads/googleads/v12/errors/types/campaign_error.py new file mode 100644 index 000000000..1af610746 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_error.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignErrorEnum",}, +) + + +class CampaignErrorEnum(proto.Message): + r"""Container for enum describing possible campaign errors. + """ + + class CampaignError(proto.Enum): + r"""Enum describing possible campaign errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_TARGET_CONTENT_NETWORK = 3 + CANNOT_TARGET_SEARCH_NETWORK = 4 + CANNOT_TARGET_SEARCH_NETWORK_WITHOUT_GOOGLE_SEARCH = 5 + CANNOT_TARGET_GOOGLE_SEARCH_FOR_CPM_CAMPAIGN = 6 + CAMPAIGN_MUST_TARGET_AT_LEAST_ONE_NETWORK = 7 + CANNOT_TARGET_PARTNER_SEARCH_NETWORK = 8 + CANNOT_TARGET_CONTENT_NETWORK_ONLY_WITH_CRITERIA_LEVEL_BIDDING_STRATEGY = ( + 9 + ) + CAMPAIGN_DURATION_MUST_CONTAIN_ALL_RUNNABLE_TRIALS = 10 + CANNOT_MODIFY_FOR_TRIAL_CAMPAIGN = 11 + DUPLICATE_CAMPAIGN_NAME = 12 + INCOMPATIBLE_CAMPAIGN_FIELD = 13 + INVALID_CAMPAIGN_NAME = 14 + INVALID_AD_SERVING_OPTIMIZATION_STATUS = 15 + INVALID_TRACKING_URL = 16 + CANNOT_SET_BOTH_TRACKING_URL_TEMPLATE_AND_TRACKING_SETTING = 17 + MAX_IMPRESSIONS_NOT_IN_RANGE = 18 + TIME_UNIT_NOT_SUPPORTED = 19 + INVALID_OPERATION_IF_SERVING_STATUS_HAS_ENDED = 20 + BUDGET_CANNOT_BE_SHARED = 21 + CAMPAIGN_CANNOT_USE_SHARED_BUDGET = 22 + CANNOT_CHANGE_BUDGET_ON_CAMPAIGN_WITH_TRIALS = 23 + CAMPAIGN_LABEL_DOES_NOT_EXIST = 24 + CAMPAIGN_LABEL_ALREADY_EXISTS = 25 + MISSING_SHOPPING_SETTING = 26 + INVALID_SHOPPING_SALES_COUNTRY = 27 + ADVERTISING_CHANNEL_TYPE_NOT_AVAILABLE_FOR_ACCOUNT_TYPE = 31 + INVALID_ADVERTISING_CHANNEL_SUB_TYPE = 32 + AT_LEAST_ONE_CONVERSION_MUST_BE_SELECTED = 33 + CANNOT_SET_AD_ROTATION_MODE = 34 + CANNOT_MODIFY_START_DATE_IF_ALREADY_STARTED = 35 + CANNOT_SET_DATE_TO_PAST = 36 + MISSING_HOTEL_CUSTOMER_LINK = 37 + INVALID_HOTEL_CUSTOMER_LINK = 38 + MISSING_HOTEL_SETTING = 39 + CANNOT_USE_SHARED_CAMPAIGN_BUDGET_WHILE_PART_OF_CAMPAIGN_GROUP = 40 + APP_NOT_FOUND = 41 + SHOPPING_ENABLE_LOCAL_NOT_SUPPORTED_FOR_CAMPAIGN_TYPE = 42 + MERCHANT_NOT_ALLOWED_FOR_COMPARISON_LISTING_ADS = 43 + INSUFFICIENT_APP_INSTALLS_COUNT = 44 + SENSITIVE_CATEGORY_APP = 45 + HEC_AGREEMENT_REQUIRED = 46 + NOT_COMPATIBLE_WITH_VIEW_THROUGH_CONVERSION_OPTIMIZATION = 49 + INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE = 48 + CANNOT_CREATE_APP_PRE_REGISTRATION_FOR_NON_ANDROID_APP = 50 + APP_NOT_AVAILABLE_TO_CREATE_APP_PRE_REGISTRATION_CAMPAIGN = 51 + INCOMPATIBLE_BUDGET_TYPE = 52 + LOCAL_SERVICES_DUPLICATE_CATEGORY_BID = 53 + LOCAL_SERVICES_INVALID_CATEGORY_BID = 54 + LOCAL_SERVICES_MISSING_CATEGORY_BID = 55 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_experiment_error.py b/google/ads/googleads/v12/errors/types/campaign_experiment_error.py new file mode 100644 index 000000000..bd0ab3d5a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_experiment_error.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignExperimentErrorEnum",}, +) + + +class CampaignExperimentErrorEnum(proto.Message): + r"""Container for enum describing possible campaign experiment + errors. + + """ + + class CampaignExperimentError(proto.Enum): + r"""Enum describing possible campaign experiment errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_NAME = 2 + INVALID_TRANSITION = 3 + CANNOT_CREATE_EXPERIMENT_WITH_SHARED_BUDGET = 4 + CANNOT_CREATE_EXPERIMENT_FOR_REMOVED_BASE_CAMPAIGN = 5 + CANNOT_CREATE_EXPERIMENT_FOR_NON_PROPOSED_DRAFT = 6 + CUSTOMER_CANNOT_CREATE_EXPERIMENT = 7 + CAMPAIGN_CANNOT_CREATE_EXPERIMENT = 8 + EXPERIMENT_DURATIONS_MUST_NOT_OVERLAP = 9 + EXPERIMENT_DURATION_MUST_BE_WITHIN_CAMPAIGN_DURATION = 10 + CANNOT_MUTATE_EXPERIMENT_DUE_TO_STATUS = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_feed_error.py b/google/ads/googleads/v12/errors/types/campaign_feed_error.py new file mode 100644 index 000000000..8492855a5 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_feed_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignFeedErrorEnum",}, +) + + +class CampaignFeedErrorEnum(proto.Message): + r"""Container for enum describing possible campaign feed errors. + """ + + class CampaignFeedError(proto.Enum): + r"""Enum describing possible campaign feed errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 2 + CANNOT_CREATE_FOR_REMOVED_FEED = 4 + CANNOT_CREATE_ALREADY_EXISTING_CAMPAIGN_FEED = 5 + CANNOT_MODIFY_REMOVED_CAMPAIGN_FEED = 6 + INVALID_PLACEHOLDER_TYPE = 7 + MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE = 8 + NO_EXISTING_LOCATION_CUSTOMER_FEED = 9 + LEGACY_FEED_TYPE_READ_ONLY = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/campaign_shared_set_error.py b/google/ads/googleads/v12/errors/types/campaign_shared_set_error.py new file mode 100644 index 000000000..361d1fcc9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/campaign_shared_set_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CampaignSharedSetErrorEnum",}, +) + + +class CampaignSharedSetErrorEnum(proto.Message): + r"""Container for enum describing possible campaign shared set + errors. + + """ + + class CampaignSharedSetError(proto.Enum): + r"""Enum describing possible campaign shared set errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SHARED_SET_ACCESS_DENIED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/change_event_error.py b/google/ads/googleads/v12/errors/types/change_event_error.py new file mode 100644 index 000000000..cf5a5036c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/change_event_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ChangeEventErrorEnum",}, +) + + +class ChangeEventErrorEnum(proto.Message): + r"""Container for enum describing possible change event errors. + """ + + class ChangeEventError(proto.Enum): + r"""Enum describing possible change event errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + START_DATE_TOO_OLD = 2 + CHANGE_DATE_RANGE_INFINITE = 3 + CHANGE_DATE_RANGE_NEGATIVE = 4 + LIMIT_NOT_SPECIFIED = 5 + INVALID_LIMIT_CLAUSE = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/change_status_error.py b/google/ads/googleads/v12/errors/types/change_status_error.py new file mode 100644 index 000000000..c193e4210 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/change_status_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ChangeStatusErrorEnum",}, +) + + +class ChangeStatusErrorEnum(proto.Message): + r"""Container for enum describing possible change status errors. + """ + + class ChangeStatusError(proto.Enum): + r"""Enum describing possible change status errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + START_DATE_TOO_OLD = 3 + CHANGE_DATE_RANGE_INFINITE = 4 + CHANGE_DATE_RANGE_NEGATIVE = 5 + LIMIT_NOT_SPECIFIED = 6 + INVALID_LIMIT_CLAUSE = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/collection_size_error.py b/google/ads/googleads/v12/errors/types/collection_size_error.py new file mode 100644 index 000000000..0328eee4c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/collection_size_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CollectionSizeErrorEnum",}, +) + + +class CollectionSizeErrorEnum(proto.Message): + r"""Container for enum describing possible collection size + errors. + + """ + + class CollectionSizeError(proto.Enum): + r"""Enum describing possible collection size errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TOO_FEW = 2 + TOO_MANY = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/context_error.py b/google/ads/googleads/v12/errors/types/context_error.py new file mode 100644 index 000000000..65f17454c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/context_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ContextErrorEnum",}, +) + + +class ContextErrorEnum(proto.Message): + r"""Container for enum describing possible context errors. + """ + + class ContextError(proto.Enum): + r"""Enum describing possible context errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPERATION_NOT_PERMITTED_FOR_CONTEXT = 2 + OPERATION_NOT_PERMITTED_FOR_REMOVED_RESOURCE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_action_error.py b/google/ads/googleads/v12/errors/types/conversion_action_error.py new file mode 100644 index 000000000..32471ad6d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_action_error.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionActionErrorEnum",}, +) + + +class ConversionActionErrorEnum(proto.Message): + r"""Container for enum describing possible conversion action + errors. + + """ + + class ConversionActionError(proto.Enum): + r"""Enum describing possible conversion action errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_NAME = 2 + DUPLICATE_APP_ID = 3 + TWO_CONVERSION_ACTIONS_BIDDING_ON_SAME_APP_DOWNLOAD = 4 + BIDDING_ON_SAME_APP_DOWNLOAD_AS_GLOBAL_ACTION = 5 + DATA_DRIVEN_MODEL_WAS_NEVER_GENERATED = 6 + DATA_DRIVEN_MODEL_EXPIRED = 7 + DATA_DRIVEN_MODEL_STALE = 8 + DATA_DRIVEN_MODEL_UNKNOWN = 9 + CREATION_NOT_SUPPORTED = 10 + UPDATE_NOT_SUPPORTED = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_adjustment_upload_error.py b/google/ads/googleads/v12/errors/types/conversion_adjustment_upload_error.py new file mode 100644 index 000000000..53492ed73 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_adjustment_upload_error.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionAdjustmentUploadErrorEnum",}, +) + + +class ConversionAdjustmentUploadErrorEnum(proto.Message): + r"""Container for enum describing possible conversion adjustment + upload errors. + + """ + + class ConversionAdjustmentUploadError(proto.Enum): + r"""Enum describing possible conversion adjustment upload errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TOO_RECENT_CONVERSION_ACTION = 2 + INVALID_CONVERSION_ACTION = 3 + CONVERSION_ALREADY_RETRACTED = 4 + CONVERSION_NOT_FOUND = 5 + CONVERSION_EXPIRED = 6 + ADJUSTMENT_PRECEDES_CONVERSION = 7 + MORE_RECENT_RESTATEMENT_FOUND = 8 + TOO_RECENT_CONVERSION = 9 + CANNOT_RESTATE_CONVERSION_ACTION_THAT_ALWAYS_USES_DEFAULT_CONVERSION_VALUE = ( + 10 + ) + TOO_MANY_ADJUSTMENTS_IN_REQUEST = 11 + TOO_MANY_ADJUSTMENTS = 12 + RESTATEMENT_ALREADY_EXISTS = 13 + DUPLICATE_ADJUSTMENT_IN_REQUEST = 14 + CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS = 15 + CONVERSION_ACTION_NOT_ELIGIBLE_FOR_ENHANCEMENT = 16 + INVALID_USER_IDENTIFIER = 17 + UNSUPPORTED_USER_IDENTIFIER = 18 + GCLID_DATE_TIME_PAIR_AND_ORDER_ID_BOTH_SET = 20 + CONVERSION_ALREADY_ENHANCED = 21 + DUPLICATE_ENHANCEMENT_IN_REQUEST = 22 + CUSTOMER_DATA_POLICY_PROHIBITS_ENHANCEMENT = 23 + MISSING_ORDER_ID_FOR_WEBPAGE = 24 + ORDER_ID_CONTAINS_PII = 25 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_custom_variable_error.py b/google/ads/googleads/v12/errors/types/conversion_custom_variable_error.py new file mode 100644 index 000000000..a8aeb6d3a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_custom_variable_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionCustomVariableErrorEnum",}, +) + + +class ConversionCustomVariableErrorEnum(proto.Message): + r"""Container for enum describing possible conversion custom + variable errors. + + """ + + class ConversionCustomVariableError(proto.Enum): + r"""Enum describing possible conversion custom variable errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_NAME = 2 + DUPLICATE_TAG = 3 + RESERVED_TAG = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_goal_campaign_config_error.py b/google/ads/googleads/v12/errors/types/conversion_goal_campaign_config_error.py new file mode 100644 index 000000000..27089156f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_goal_campaign_config_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionGoalCampaignConfigErrorEnum",}, +) + + +class ConversionGoalCampaignConfigErrorEnum(proto.Message): + r"""Container for enum describing possible conversion goal + campaign config errors. + + """ + + class ConversionGoalCampaignConfigError(proto.Enum): + r"""Enum describing possible conversion goal campaign config + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_USE_CAMPAIGN_GOAL_FOR_SEARCH_ADS_360_MANAGED_CAMPAIGN = 2 + CUSTOM_GOAL_DOES_NOT_BELONG_TO_GOOGLE_ADS_CONVERSION_CUSTOMER = 3 + CAMPAIGN_CANNOT_USE_UNIFIED_GOALS = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_upload_error.py b/google/ads/googleads/v12/errors/types/conversion_upload_error.py new file mode 100644 index 000000000..5b75a3bdd --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_upload_error.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionUploadErrorEnum",}, +) + + +class ConversionUploadErrorEnum(proto.Message): + r"""Container for enum describing possible conversion upload + errors. + + """ + + class ConversionUploadError(proto.Enum): + r"""Enum describing possible conversion upload errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TOO_MANY_CONVERSIONS_IN_REQUEST = 2 + UNPARSEABLE_GCLID = 3 + CONVERSION_PRECEDES_EVENT = 42 + EXPIRED_EVENT = 43 + TOO_RECENT_EVENT = 44 + EVENT_NOT_FOUND = 45 + UNAUTHORIZED_CUSTOMER = 8 + INVALID_CONVERSION_ACTION = 9 + TOO_RECENT_CONVERSION_ACTION = 10 + CONVERSION_TRACKING_NOT_ENABLED_AT_IMPRESSION_TIME = 11 + EXTERNAL_ATTRIBUTION_DATA_SET_FOR_NON_EXTERNALLY_ATTRIBUTED_CONVERSION_ACTION = ( + 12 + ) + EXTERNAL_ATTRIBUTION_DATA_NOT_SET_FOR_EXTERNALLY_ATTRIBUTED_CONVERSION_ACTION = ( + 13 + ) + ORDER_ID_NOT_PERMITTED_FOR_EXTERNALLY_ATTRIBUTED_CONVERSION_ACTION = 14 + ORDER_ID_ALREADY_IN_USE = 15 + DUPLICATE_ORDER_ID = 16 + TOO_RECENT_CALL = 17 + EXPIRED_CALL = 18 + CALL_NOT_FOUND = 19 + CONVERSION_PRECEDES_CALL = 20 + CONVERSION_TRACKING_NOT_ENABLED_AT_CALL_TIME = 21 + UNPARSEABLE_CALLERS_PHONE_NUMBER = 22 + CLICK_CONVERSION_ALREADY_EXISTS = 23 + CALL_CONVERSION_ALREADY_EXISTS = 24 + DUPLICATE_CLICK_CONVERSION_IN_REQUEST = 25 + DUPLICATE_CALL_CONVERSION_IN_REQUEST = 26 + CUSTOM_VARIABLE_NOT_ENABLED = 28 + CUSTOM_VARIABLE_VALUE_CONTAINS_PII = 29 + INVALID_CUSTOMER_FOR_CLICK = 30 + INVALID_CUSTOMER_FOR_CALL = 31 + CONVERSION_NOT_COMPLIANT_WITH_ATT_POLICY = 32 + CLICK_NOT_FOUND = 33 + INVALID_USER_IDENTIFIER = 34 + EXTERNALLY_ATTRIBUTED_CONVERSION_ACTION_NOT_PERMITTED_WITH_USER_IDENTIFIER = ( + 35 + ) + UNSUPPORTED_USER_IDENTIFIER = 36 + GBRAID_WBRAID_BOTH_SET = 38 + UNPARSEABLE_WBRAID = 39 + UNPARSEABLE_GBRAID = 40 + ONE_PER_CLICK_CONVERSION_ACTION_NOT_PERMITTED_WITH_BRAID = 46 + CUSTOMER_DATA_POLICY_PROHIBITS_ENHANCED_CONVERSIONS = 47 + CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS = 48 + ORDER_ID_CONTAINS_PII = 49 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_value_rule_error.py b/google/ads/googleads/v12/errors/types/conversion_value_rule_error.py new file mode 100644 index 000000000..ad8e13cc0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_value_rule_error.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRuleErrorEnum",}, +) + + +class ConversionValueRuleErrorEnum(proto.Message): + r"""Container for enum describing possible conversion value rule + errors. + + """ + + class ConversionValueRuleError(proto.Enum): + r"""Enum describing possible conversion value rule errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_GEO_TARGET_CONSTANT = 2 + CONFLICTING_INCLUDED_AND_EXCLUDED_GEO_TARGET = 3 + CONFLICTING_CONDITIONS = 4 + CANNOT_REMOVE_IF_INCLUDED_IN_VALUE_RULE_SET = 5 + CONDITION_NOT_ALLOWED = 6 + FIELD_MUST_BE_UNSET = 7 + CANNOT_PAUSE_UNLESS_VALUE_RULE_SET_IS_PAUSED = 8 + UNTARGETABLE_GEO_TARGET = 9 + INVALID_AUDIENCE_USER_LIST = 10 + INACCESSIBLE_USER_LIST = 11 + INVALID_AUDIENCE_USER_INTEREST = 12 + CANNOT_ADD_RULE_WITH_STATUS_REMOVED = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/conversion_value_rule_set_error.py b/google/ads/googleads/v12/errors/types/conversion_value_rule_set_error.py new file mode 100644 index 000000000..95433c3e3 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/conversion_value_rule_set_error.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRuleSetErrorEnum",}, +) + + +class ConversionValueRuleSetErrorEnum(proto.Message): + r"""Container for enum describing possible conversion value rule + set errors. + + """ + + class ConversionValueRuleSetError(proto.Enum): + r"""Enum describing possible conversion value rule set errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CONFLICTING_VALUE_RULE_CONDITIONS = 2 + INVALID_VALUE_RULE = 3 + DIMENSIONS_UPDATE_ONLY_ALLOW_APPEND = 4 + CONDITION_TYPE_NOT_ALLOWED = 5 + DUPLICATE_DIMENSIONS = 6 + INVALID_CAMPAIGN_ID = 7 + CANNOT_PAUSE_UNLESS_ALL_VALUE_RULES_ARE_PAUSED = 8 + SHOULD_PAUSE_WHEN_ALL_VALUE_RULES_ARE_PAUSED = 9 + VALUE_RULES_NOT_SUPPORTED_FOR_CAMPAIGN_TYPE = 10 + INELIGIBLE_CONVERSION_ACTION_CATEGORIES = 11 + DIMENSION_NO_CONDITION_USED_WITH_OTHER_DIMENSIONS = 12 + DIMENSION_NO_CONDITION_NOT_ALLOWED = 13 + UNSUPPORTED_CONVERSION_ACTION_CATEGORIES = 14 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/country_code_error.py b/google/ads/googleads/v12/errors/types/country_code_error.py new file mode 100644 index 000000000..563462033 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/country_code_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CountryCodeErrorEnum",}, +) + + +class CountryCodeErrorEnum(proto.Message): + r"""Container for enum describing country code errors. + """ + + class CountryCodeError(proto.Enum): + r"""Enum describing country code errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_COUNTRY_CODE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/criterion_error.py b/google/ads/googleads/v12/errors/types/criterion_error.py new file mode 100644 index 000000000..a281a48c6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/criterion_error.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CriterionErrorEnum",}, +) + + +class CriterionErrorEnum(proto.Message): + r"""Container for enum describing possible criterion errors. + """ + + class CriterionError(proto.Enum): + r"""Enum describing possible criterion errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CONCRETE_TYPE_REQUIRED = 2 + INVALID_EXCLUDED_CATEGORY = 3 + INVALID_KEYWORD_TEXT = 4 + KEYWORD_TEXT_TOO_LONG = 5 + KEYWORD_HAS_TOO_MANY_WORDS = 6 + KEYWORD_HAS_INVALID_CHARS = 7 + INVALID_PLACEMENT_URL = 8 + INVALID_USER_LIST = 9 + INVALID_USER_INTEREST = 10 + INVALID_FORMAT_FOR_PLACEMENT_URL = 11 + PLACEMENT_URL_IS_TOO_LONG = 12 + PLACEMENT_URL_HAS_ILLEGAL_CHAR = 13 + PLACEMENT_URL_HAS_MULTIPLE_SITES_IN_LINE = 14 + PLACEMENT_IS_NOT_AVAILABLE_FOR_TARGETING_OR_EXCLUSION = 15 + INVALID_TOPIC_PATH = 16 + INVALID_YOUTUBE_CHANNEL_ID = 17 + INVALID_YOUTUBE_VIDEO_ID = 18 + YOUTUBE_VERTICAL_CHANNEL_DEPRECATED = 19 + YOUTUBE_DEMOGRAPHIC_CHANNEL_DEPRECATED = 20 + YOUTUBE_URL_UNSUPPORTED = 21 + CANNOT_EXCLUDE_CRITERIA_TYPE = 22 + CANNOT_ADD_CRITERIA_TYPE = 23 + CANNOT_EXCLUDE_SIMILAR_USER_LIST = 26 + CANNOT_ADD_CLOSED_USER_LIST = 27 + CANNOT_ADD_DISPLAY_ONLY_LISTS_TO_SEARCH_ONLY_CAMPAIGNS = 28 + CANNOT_ADD_DISPLAY_ONLY_LISTS_TO_SEARCH_CAMPAIGNS = 29 + CANNOT_ADD_DISPLAY_ONLY_LISTS_TO_SHOPPING_CAMPAIGNS = 30 + CANNOT_ADD_USER_INTERESTS_TO_SEARCH_CAMPAIGNS = 31 + CANNOT_SET_BIDS_ON_CRITERION_TYPE_IN_SEARCH_CAMPAIGNS = 32 + CANNOT_ADD_URLS_TO_CRITERION_TYPE_FOR_CAMPAIGN_TYPE = 33 + INVALID_COMBINED_AUDIENCE = 122 + INVALID_CUSTOM_AFFINITY = 96 + INVALID_CUSTOM_INTENT = 97 + INVALID_CUSTOM_AUDIENCE = 121 + INVALID_IP_ADDRESS = 34 + INVALID_IP_FORMAT = 35 + INVALID_MOBILE_APP = 36 + INVALID_MOBILE_APP_CATEGORY = 37 + INVALID_CRITERION_ID = 38 + CANNOT_TARGET_CRITERION = 39 + CANNOT_TARGET_OBSOLETE_CRITERION = 40 + CRITERION_ID_AND_TYPE_MISMATCH = 41 + INVALID_PROXIMITY_RADIUS = 42 + INVALID_PROXIMITY_RADIUS_UNITS = 43 + INVALID_STREETADDRESS_LENGTH = 44 + INVALID_CITYNAME_LENGTH = 45 + INVALID_REGIONCODE_LENGTH = 46 + INVALID_REGIONNAME_LENGTH = 47 + INVALID_POSTALCODE_LENGTH = 48 + INVALID_COUNTRY_CODE = 49 + INVALID_LATITUDE = 50 + INVALID_LONGITUDE = 51 + PROXIMITY_GEOPOINT_AND_ADDRESS_BOTH_CANNOT_BE_NULL = 52 + INVALID_PROXIMITY_ADDRESS = 53 + INVALID_USER_DOMAIN_NAME = 54 + CRITERION_PARAMETER_TOO_LONG = 55 + AD_SCHEDULE_TIME_INTERVALS_OVERLAP = 56 + AD_SCHEDULE_INTERVAL_CANNOT_SPAN_MULTIPLE_DAYS = 57 + AD_SCHEDULE_INVALID_TIME_INTERVAL = 58 + AD_SCHEDULE_EXCEEDED_INTERVALS_PER_DAY_LIMIT = 59 + AD_SCHEDULE_CRITERION_ID_MISMATCHING_FIELDS = 60 + CANNOT_BID_MODIFY_CRITERION_TYPE = 61 + CANNOT_BID_MODIFY_CRITERION_CAMPAIGN_OPTED_OUT = 62 + CANNOT_BID_MODIFY_NEGATIVE_CRITERION = 63 + BID_MODIFIER_ALREADY_EXISTS = 64 + FEED_ID_NOT_ALLOWED = 65 + ACCOUNT_INELIGIBLE_FOR_CRITERIA_TYPE = 66 + CRITERIA_TYPE_INVALID_FOR_BIDDING_STRATEGY = 67 + CANNOT_EXCLUDE_CRITERION = 68 + CANNOT_REMOVE_CRITERION = 69 + INVALID_PRODUCT_BIDDING_CATEGORY = 76 + MISSING_SHOPPING_SETTING = 77 + INVALID_MATCHING_FUNCTION = 78 + LOCATION_FILTER_NOT_ALLOWED = 79 + INVALID_FEED_FOR_LOCATION_FILTER = 98 + LOCATION_FILTER_INVALID = 80 + CANNOT_SET_GEO_TARGET_CONSTANTS_WITH_FEED_ITEM_SETS = 123 + CANNOT_SET_BOTH_ASSET_SET_AND_FEED = 140 + CANNOT_SET_FEED_OR_FEED_ITEM_SETS_FOR_CUSTOMER = 142 + CANNOT_SET_ASSET_SET_FIELD_FOR_CUSTOMER = 150 + CANNOT_SET_GEO_TARGET_CONSTANTS_WITH_ASSET_SETS = 143 + CANNOT_SET_ASSET_SETS_WITH_FEED_ITEM_SETS = 144 + INVALID_LOCATION_GROUP_ASSET_SET = 141 + INVALID_LOCATION_GROUP_RADIUS = 124 + INVALID_LOCATION_GROUP_RADIUS_UNIT = 125 + CANNOT_ATTACH_CRITERIA_AT_CAMPAIGN_AND_ADGROUP = 81 + HOTEL_LENGTH_OF_STAY_OVERLAPS_WITH_EXISTING_CRITERION = 82 + HOTEL_ADVANCE_BOOKING_WINDOW_OVERLAPS_WITH_EXISTING_CRITERION = 83 + FIELD_INCOMPATIBLE_WITH_NEGATIVE_TARGETING = 84 + INVALID_WEBPAGE_CONDITION = 85 + INVALID_WEBPAGE_CONDITION_URL = 86 + WEBPAGE_CONDITION_URL_CANNOT_BE_EMPTY = 87 + WEBPAGE_CONDITION_URL_UNSUPPORTED_PROTOCOL = 88 + WEBPAGE_CONDITION_URL_CANNOT_BE_IP_ADDRESS = 89 + WEBPAGE_CONDITION_URL_DOMAIN_NOT_CONSISTENT_WITH_CAMPAIGN_SETTING = 90 + WEBPAGE_CONDITION_URL_CANNOT_BE_PUBLIC_SUFFIX = 91 + WEBPAGE_CONDITION_URL_INVALID_PUBLIC_SUFFIX = 92 + WEBPAGE_CONDITION_URL_VALUE_TRACK_VALUE_NOT_SUPPORTED = 93 + WEBPAGE_CRITERION_URL_EQUALS_CAN_HAVE_ONLY_ONE_CONDITION = 94 + WEBPAGE_CRITERION_NOT_SUPPORTED_ON_NON_DSA_AD_GROUP = 95 + CANNOT_TARGET_USER_LIST_FOR_SMART_DISPLAY_CAMPAIGNS = 99 + CANNOT_TARGET_PLACEMENTS_FOR_SEARCH_CAMPAIGNS = 126 + LISTING_SCOPE_TOO_MANY_DIMENSION_TYPES = 100 + LISTING_SCOPE_TOO_MANY_IN_OPERATORS = 101 + LISTING_SCOPE_IN_OPERATOR_NOT_SUPPORTED = 102 + DUPLICATE_LISTING_DIMENSION_TYPE = 103 + DUPLICATE_LISTING_DIMENSION_VALUE = 104 + CANNOT_SET_BIDS_ON_LISTING_GROUP_SUBDIVISION = 105 + INVALID_LISTING_GROUP_HIERARCHY = 106 + LISTING_GROUP_UNIT_CANNOT_HAVE_CHILDREN = 107 + LISTING_GROUP_SUBDIVISION_REQUIRES_OTHERS_CASE = 108 + LISTING_GROUP_REQUIRES_SAME_DIMENSION_TYPE_AS_SIBLINGS = 109 + LISTING_GROUP_ALREADY_EXISTS = 110 + LISTING_GROUP_DOES_NOT_EXIST = 111 + LISTING_GROUP_CANNOT_BE_REMOVED = 112 + INVALID_LISTING_GROUP_TYPE = 113 + LISTING_GROUP_ADD_MAY_ONLY_USE_TEMP_ID = 114 + LISTING_SCOPE_TOO_LONG = 115 + LISTING_SCOPE_TOO_MANY_DIMENSIONS = 116 + LISTING_GROUP_TOO_LONG = 117 + LISTING_GROUP_TREE_TOO_DEEP = 118 + INVALID_LISTING_DIMENSION = 119 + INVALID_LISTING_DIMENSION_TYPE = 120 + ADVERTISER_NOT_ON_ALLOWLIST_FOR_COMBINED_AUDIENCE_ON_DISPLAY = 127 + CANNOT_TARGET_REMOVED_COMBINED_AUDIENCE = 128 + INVALID_COMBINED_AUDIENCE_ID = 129 + CANNOT_TARGET_REMOVED_CUSTOM_AUDIENCE = 130 + HOTEL_CHECK_IN_DATE_RANGE_OVERLAPS_WITH_EXISTING_CRITERION = 131 + HOTEL_CHECK_IN_DATE_RANGE_START_DATE_TOO_EARLY = 132 + HOTEL_CHECK_IN_DATE_RANGE_END_DATE_TOO_LATE = 133 + HOTEL_CHECK_IN_DATE_RANGE_REVERSED = 134 + BROAD_MATCH_MODIFIER_KEYWORD_NOT_ALLOWED = 135 + ONE_AUDIENCE_ALLOWED_PER_ASSET_GROUP = 136 + AUDIENCE_NOT_ELIGIBLE_FOR_CAMPAIGN_TYPE = 137 + AUDIENCE_NOT_ALLOWED_TO_ATTACH_WHEN_AUDIENCE_GROUPED_SET_TO_FALSE = 138 + CANNOT_TARGET_CUSTOMER_MATCH_USER_LIST = 139 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/currency_code_error.py b/google/ads/googleads/v12/errors/types/currency_code_error.py new file mode 100644 index 000000000..711105aaf --- /dev/null +++ b/google/ads/googleads/v12/errors/types/currency_code_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CurrencyCodeErrorEnum",}, +) + + +class CurrencyCodeErrorEnum(proto.Message): + r"""Container for enum describing possible currency code errors. + """ + + class CurrencyCodeError(proto.Enum): + r"""Enum describing possible currency code errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNSUPPORTED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/custom_audience_error.py b/google/ads/googleads/v12/errors/types/custom_audience_error.py new file mode 100644 index 000000000..12e96d9c7 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/custom_audience_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomAudienceErrorEnum",}, +) + + +class CustomAudienceErrorEnum(proto.Message): + r"""Container for enum describing possible custom audience + errors. + + """ + + class CustomAudienceError(proto.Enum): + r"""Enum describing possible custom audience errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NAME_ALREADY_USED = 2 + CANNOT_REMOVE_WHILE_IN_USE = 3 + RESOURCE_ALREADY_REMOVED = 4 + MEMBER_TYPE_AND_PARAMETER_ALREADY_EXISTED = 5 + INVALID_MEMBER_TYPE = 6 + MEMBER_TYPE_AND_VALUE_DOES_NOT_MATCH = 7 + POLICY_VIOLATION = 8 + INVALID_TYPE_CHANGE = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/custom_conversion_goal_error.py b/google/ads/googleads/v12/errors/types/custom_conversion_goal_error.py new file mode 100644 index 000000000..ac2201d04 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/custom_conversion_goal_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomConversionGoalErrorEnum",}, +) + + +class CustomConversionGoalErrorEnum(proto.Message): + r"""Container for enum describing possible custom conversion goal + errors. + + """ + + class CustomConversionGoalError(proto.Enum): + r"""Enum describing possible custom conversion goal errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_CONVERSION_ACTION = 2 + CONVERSION_ACTION_NOT_ENABLED = 3 + CANNOT_REMOVE_LINKED_CUSTOM_CONVERSION_GOAL = 4 + CUSTOM_GOAL_DUPLICATE_NAME = 5 + DUPLICATE_CONVERSION_ACTION_LIST = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/custom_interest_error.py b/google/ads/googleads/v12/errors/types/custom_interest_error.py new file mode 100644 index 000000000..7a48b7dd0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/custom_interest_error.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomInterestErrorEnum",}, +) + + +class CustomInterestErrorEnum(proto.Message): + r"""Container for enum describing possible custom interest + errors. + + """ + + class CustomInterestError(proto.Enum): + r"""Enum describing possible custom interest errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NAME_ALREADY_USED = 2 + CUSTOM_INTEREST_MEMBER_ID_AND_TYPE_PARAMETER_NOT_PRESENT_IN_REMOVE = 3 + TYPE_AND_PARAMETER_NOT_FOUND = 4 + TYPE_AND_PARAMETER_ALREADY_EXISTED = 5 + INVALID_CUSTOM_INTEREST_MEMBER_TYPE = 6 + CANNOT_REMOVE_WHILE_IN_USE = 7 + CANNOT_CHANGE_TYPE = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_client_link_error.py b/google/ads/googleads/v12/errors/types/customer_client_link_error.py new file mode 100644 index 000000000..943221196 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_client_link_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerClientLinkErrorEnum",}, +) + + +class CustomerClientLinkErrorEnum(proto.Message): + r"""Container for enum describing possible CustomeClientLink + errors. + + """ + + class CustomerClientLinkError(proto.Enum): + r"""Enum describing possible CustomerClientLink errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CLIENT_ALREADY_INVITED_BY_THIS_MANAGER = 2 + CLIENT_ALREADY_MANAGED_IN_HIERARCHY = 3 + CYCLIC_LINK_NOT_ALLOWED = 4 + CUSTOMER_HAS_TOO_MANY_ACCOUNTS = 5 + CLIENT_HAS_TOO_MANY_INVITATIONS = 6 + CANNOT_HIDE_OR_UNHIDE_MANAGER_ACCOUNTS = 7 + CUSTOMER_HAS_TOO_MANY_ACCOUNTS_AT_MANAGER = 8 + CLIENT_HAS_TOO_MANY_MANAGERS = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_customizer_error.py b/google/ads/googleads/v12/errors/types/customer_customizer_error.py new file mode 100644 index 000000000..c4ab577ec --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_customizer_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerCustomizerErrorEnum",}, +) + + +class CustomerCustomizerErrorEnum(proto.Message): + r"""Container for enum describing possible customer customizer + errors. + + """ + + class CustomerCustomizerError(proto.Enum): + r"""Enum describing possible customer customizer errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_error.py b/google/ads/googleads/v12/errors/types/customer_error.py new file mode 100644 index 000000000..89e5a6fcb --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerErrorEnum",}, +) + + +class CustomerErrorEnum(proto.Message): + r"""Container for enum describing possible customer errors. + """ + + class CustomerError(proto.Enum): + r"""Set of errors that are related to requests dealing with + Customer. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + STATUS_CHANGE_DISALLOWED = 2 + ACCOUNT_NOT_SET_UP = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_feed_error.py b/google/ads/googleads/v12/errors/types/customer_feed_error.py new file mode 100644 index 000000000..1f136adde --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_feed_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerFeedErrorEnum",}, +) + + +class CustomerFeedErrorEnum(proto.Message): + r"""Container for enum describing possible customer feed errors. + """ + + class CustomerFeedError(proto.Enum): + r"""Enum describing possible customer feed errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 2 + CANNOT_CREATE_FOR_REMOVED_FEED = 3 + CANNOT_CREATE_ALREADY_EXISTING_CUSTOMER_FEED = 4 + CANNOT_MODIFY_REMOVED_CUSTOMER_FEED = 5 + INVALID_PLACEHOLDER_TYPE = 6 + MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE = 7 + PLACEHOLDER_TYPE_NOT_ALLOWED_ON_CUSTOMER_FEED = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_manager_link_error.py b/google/ads/googleads/v12/errors/types/customer_manager_link_error.py new file mode 100644 index 000000000..739a648ec --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_manager_link_error.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerManagerLinkErrorEnum",}, +) + + +class CustomerManagerLinkErrorEnum(proto.Message): + r"""Container for enum describing possible CustomerManagerLink + errors. + + """ + + class CustomerManagerLinkError(proto.Enum): + r"""Enum describing possible CustomerManagerLink errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_PENDING_INVITE = 2 + SAME_CLIENT_MORE_THAN_ONCE_PER_CALL = 3 + MANAGER_HAS_MAX_NUMBER_OF_LINKED_ACCOUNTS = 4 + CANNOT_UNLINK_ACCOUNT_WITHOUT_ACTIVE_USER = 5 + CANNOT_REMOVE_LAST_CLIENT_ACCOUNT_OWNER = 6 + CANNOT_CHANGE_ROLE_BY_NON_ACCOUNT_OWNER = 7 + CANNOT_CHANGE_ROLE_FOR_NON_ACTIVE_LINK_ACCOUNT = 8 + DUPLICATE_CHILD_FOUND = 9 + TEST_ACCOUNT_LINKS_TOO_MANY_CHILD_ACCOUNTS = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customer_user_access_error.py b/google/ads/googleads/v12/errors/types/customer_user_access_error.py new file mode 100644 index 000000000..47a23db33 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customer_user_access_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomerUserAccessErrorEnum",}, +) + + +class CustomerUserAccessErrorEnum(proto.Message): + r"""Container for enum describing possible CustomerUserAccess + errors. + + """ + + class CustomerUserAccessError(proto.Enum): + r"""Enum describing possible customer user access errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_USER_ID = 2 + REMOVAL_DISALLOWED = 3 + DISALLOWED_ACCESS_ROLE = 4 + LAST_ADMIN_USER_OF_SERVING_CUSTOMER = 5 + LAST_ADMIN_USER_OF_MANAGER = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/customizer_attribute_error.py b/google/ads/googleads/v12/errors/types/customizer_attribute_error.py new file mode 100644 index 000000000..679c3437e --- /dev/null +++ b/google/ads/googleads/v12/errors/types/customizer_attribute_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"CustomizerAttributeErrorEnum",}, +) + + +class CustomizerAttributeErrorEnum(proto.Message): + r"""Container for enum describing possible customizer attribute + errors. + + """ + + class CustomizerAttributeError(proto.Enum): + r"""Enum describing possible customizer attribute errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_CUSTOMIZER_ATTRIBUTE_NAME = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/database_error.py b/google/ads/googleads/v12/errors/types/database_error.py new file mode 100644 index 000000000..faf32d14c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/database_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"DatabaseErrorEnum",}, +) + + +class DatabaseErrorEnum(proto.Message): + r"""Container for enum describing possible database errors. + """ + + class DatabaseError(proto.Enum): + r"""Enum describing possible database errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CONCURRENT_MODIFICATION = 2 + DATA_CONSTRAINT_VIOLATION = 3 + REQUEST_TOO_LARGE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/date_error.py b/google/ads/googleads/v12/errors/types/date_error.py new file mode 100644 index 000000000..f03594f5c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/date_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"DateErrorEnum",}, +) + + +class DateErrorEnum(proto.Message): + r"""Container for enum describing possible date errors. + """ + + class DateError(proto.Enum): + r"""Enum describing possible date errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_FIELD_VALUES_IN_DATE = 2 + INVALID_FIELD_VALUES_IN_DATE_TIME = 3 + INVALID_STRING_DATE = 4 + INVALID_STRING_DATE_TIME_MICROS = 6 + INVALID_STRING_DATE_TIME_SECONDS = 11 + INVALID_STRING_DATE_TIME_SECONDS_WITH_OFFSET = 12 + EARLIER_THAN_MINIMUM_DATE = 7 + LATER_THAN_MAXIMUM_DATE = 8 + DATE_RANGE_MINIMUM_DATE_LATER_THAN_MAXIMUM_DATE = 9 + DATE_RANGE_MINIMUM_AND_MAXIMUM_DATES_BOTH_NULL = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/date_range_error.py b/google/ads/googleads/v12/errors/types/date_range_error.py new file mode 100644 index 000000000..26efe5096 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/date_range_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"DateRangeErrorEnum",}, +) + + +class DateRangeErrorEnum(proto.Message): + r"""Container for enum describing possible date range errors. + """ + + class DateRangeError(proto.Enum): + r"""Enum describing possible date range errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_DATE = 2 + START_DATE_AFTER_END_DATE = 3 + CANNOT_SET_DATE_TO_PAST = 4 + AFTER_MAXIMUM_ALLOWABLE_DATE = 5 + CANNOT_MODIFY_START_DATE_IF_ALREADY_STARTED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/distinct_error.py b/google/ads/googleads/v12/errors/types/distinct_error.py new file mode 100644 index 000000000..58cd07361 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/distinct_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"DistinctErrorEnum",}, +) + + +class DistinctErrorEnum(proto.Message): + r"""Container for enum describing possible distinct errors. + """ + + class DistinctError(proto.Enum): + r"""Enum describing possible distinct errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_ELEMENT = 2 + DUPLICATE_TYPE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/enum_error.py b/google/ads/googleads/v12/errors/types/enum_error.py new file mode 100644 index 000000000..180165a67 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/enum_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"EnumErrorEnum",}, +) + + +class EnumErrorEnum(proto.Message): + r"""Container for enum describing possible enum errors. + """ + + class EnumError(proto.Enum): + r"""Enum describing possible enum errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ENUM_VALUE_NOT_PERMITTED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/errors.py b/google/ads/googleads/v12/errors/types/errors.py new file mode 100644 index 000000000..82132736a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/errors.py @@ -0,0 +1,2132 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.common.types import value +from google.ads.googleads.v12.enums.types import resource_limit_type +from google.ads.googleads.v12.errors.types import ( + access_invitation_error as gage_access_invitation_error, +) +from google.ads.googleads.v12.errors.types import ( + account_budget_proposal_error as gage_account_budget_proposal_error, +) +from google.ads.googleads.v12.errors.types import ( + account_link_error as gage_account_link_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_customizer_error as gage_ad_customizer_error, +) +from google.ads.googleads.v12.errors.types import ad_error as gage_ad_error +from google.ads.googleads.v12.errors.types import ( + ad_group_ad_error as gage_ad_group_ad_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_bid_modifier_error as gage_ad_group_bid_modifier_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_criterion_customizer_error as gage_ad_group_criterion_customizer_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_criterion_error as gage_ad_group_criterion_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_customizer_error as gage_ad_group_customizer_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_error as gage_ad_group_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_group_feed_error as gage_ad_group_feed_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_parameter_error as gage_ad_parameter_error, +) +from google.ads.googleads.v12.errors.types import ( + ad_sharing_error as gage_ad_sharing_error, +) +from google.ads.googleads.v12.errors.types import adx_error as gage_adx_error +from google.ads.googleads.v12.errors.types import ( + asset_error as gage_asset_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_group_asset_error as gage_asset_group_asset_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_group_error as gage_asset_group_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_group_listing_group_filter_error as gage_asset_group_listing_group_filter_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_link_error as gage_asset_link_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_set_asset_error as gage_asset_set_asset_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_set_error as gage_asset_set_error, +) +from google.ads.googleads.v12.errors.types import ( + asset_set_link_error as gage_asset_set_link_error, +) +from google.ads.googleads.v12.errors.types import ( + audience_error as gage_audience_error, +) +from google.ads.googleads.v12.errors.types import ( + audience_insights_error as gage_audience_insights_error, +) +from google.ads.googleads.v12.errors.types import ( + authentication_error as gage_authentication_error, +) +from google.ads.googleads.v12.errors.types import ( + authorization_error as gage_authorization_error, +) +from google.ads.googleads.v12.errors.types import ( + batch_job_error as gage_batch_job_error, +) +from google.ads.googleads.v12.errors.types import ( + bidding_error as gage_bidding_error, +) +from google.ads.googleads.v12.errors.types import ( + bidding_strategy_error as gage_bidding_strategy_error, +) +from google.ads.googleads.v12.errors.types import ( + billing_setup_error as gage_billing_setup_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_budget_error as gage_campaign_budget_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_conversion_goal_error as gage_campaign_conversion_goal_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_criterion_error as gage_campaign_criterion_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_customizer_error as gage_campaign_customizer_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_draft_error as gage_campaign_draft_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_error as gage_campaign_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_experiment_error as gage_campaign_experiment_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_feed_error as gage_campaign_feed_error, +) +from google.ads.googleads.v12.errors.types import ( + campaign_shared_set_error as gage_campaign_shared_set_error, +) +from google.ads.googleads.v12.errors.types import ( + change_event_error as gage_change_event_error, +) +from google.ads.googleads.v12.errors.types import ( + change_status_error as gage_change_status_error, +) +from google.ads.googleads.v12.errors.types import ( + collection_size_error as gage_collection_size_error, +) +from google.ads.googleads.v12.errors.types import ( + context_error as gage_context_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_action_error as gage_conversion_action_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_adjustment_upload_error as gage_conversion_adjustment_upload_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_custom_variable_error as gage_conversion_custom_variable_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_goal_campaign_config_error as gage_conversion_goal_campaign_config_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_upload_error as gage_conversion_upload_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_value_rule_error as gage_conversion_value_rule_error, +) +from google.ads.googleads.v12.errors.types import ( + conversion_value_rule_set_error as gage_conversion_value_rule_set_error, +) +from google.ads.googleads.v12.errors.types import ( + country_code_error as gage_country_code_error, +) +from google.ads.googleads.v12.errors.types import ( + criterion_error as gage_criterion_error, +) +from google.ads.googleads.v12.errors.types import ( + currency_code_error as gage_currency_code_error, +) +from google.ads.googleads.v12.errors.types import ( + custom_audience_error as gage_custom_audience_error, +) +from google.ads.googleads.v12.errors.types import ( + custom_conversion_goal_error as gage_custom_conversion_goal_error, +) +from google.ads.googleads.v12.errors.types import ( + custom_interest_error as gage_custom_interest_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_client_link_error as gage_customer_client_link_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_customizer_error as gage_customer_customizer_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_error as gage_customer_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_feed_error as gage_customer_feed_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_manager_link_error as gage_customer_manager_link_error, +) +from google.ads.googleads.v12.errors.types import ( + customer_user_access_error as gage_customer_user_access_error, +) +from google.ads.googleads.v12.errors.types import ( + customizer_attribute_error as gage_customizer_attribute_error, +) +from google.ads.googleads.v12.errors.types import ( + database_error as gage_database_error, +) +from google.ads.googleads.v12.errors.types import date_error as gage_date_error +from google.ads.googleads.v12.errors.types import ( + date_range_error as gage_date_range_error, +) +from google.ads.googleads.v12.errors.types import ( + distinct_error as gage_distinct_error, +) +from google.ads.googleads.v12.errors.types import enum_error as gage_enum_error +from google.ads.googleads.v12.errors.types import ( + experiment_arm_error as gage_experiment_arm_error, +) +from google.ads.googleads.v12.errors.types import ( + experiment_error as gage_experiment_error, +) +from google.ads.googleads.v12.errors.types import ( + extension_feed_item_error as gage_extension_feed_item_error, +) +from google.ads.googleads.v12.errors.types import ( + extension_setting_error as gage_extension_setting_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_attribute_reference_error as gage_feed_attribute_reference_error, +) +from google.ads.googleads.v12.errors.types import feed_error as gage_feed_error +from google.ads.googleads.v12.errors.types import ( + feed_item_error as gage_feed_item_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_item_set_error as gage_feed_item_set_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_item_set_link_error as gage_feed_item_set_link_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_item_target_error as gage_feed_item_target_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_item_validation_error as gage_feed_item_validation_error, +) +from google.ads.googleads.v12.errors.types import ( + feed_mapping_error as gage_feed_mapping_error, +) +from google.ads.googleads.v12.errors.types import ( + field_error as gage_field_error, +) +from google.ads.googleads.v12.errors.types import ( + field_mask_error as gage_field_mask_error, +) +from google.ads.googleads.v12.errors.types import ( + function_error as gage_function_error, +) +from google.ads.googleads.v12.errors.types import ( + function_parsing_error as gage_function_parsing_error, +) +from google.ads.googleads.v12.errors.types import ( + geo_target_constant_suggestion_error as gage_geo_target_constant_suggestion_error, +) +from google.ads.googleads.v12.errors.types import ( + header_error as gage_header_error, +) +from google.ads.googleads.v12.errors.types import id_error as gage_id_error +from google.ads.googleads.v12.errors.types import ( + image_error as gage_image_error, +) +from google.ads.googleads.v12.errors.types import ( + internal_error as gage_internal_error, +) +from google.ads.googleads.v12.errors.types import ( + invoice_error as gage_invoice_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_ad_group_error as gage_keyword_plan_ad_group_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_ad_group_keyword_error as gage_keyword_plan_ad_group_keyword_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_campaign_error as gage_keyword_plan_campaign_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_campaign_keyword_error as gage_keyword_plan_campaign_keyword_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_error as gage_keyword_plan_error, +) +from google.ads.googleads.v12.errors.types import ( + keyword_plan_idea_error as gage_keyword_plan_idea_error, +) +from google.ads.googleads.v12.errors.types import ( + label_error as gage_label_error, +) +from google.ads.googleads.v12.errors.types import ( + language_code_error as gage_language_code_error, +) +from google.ads.googleads.v12.errors.types import ( + list_operation_error as gage_list_operation_error, +) +from google.ads.googleads.v12.errors.types import ( + manager_link_error as gage_manager_link_error, +) +from google.ads.googleads.v12.errors.types import ( + media_bundle_error as gage_media_bundle_error, +) +from google.ads.googleads.v12.errors.types import ( + media_file_error as gage_media_file_error, +) +from google.ads.googleads.v12.errors.types import ( + media_upload_error as gage_media_upload_error, +) +from google.ads.googleads.v12.errors.types import ( + merchant_center_error as gage_merchant_center_error, +) +from google.ads.googleads.v12.errors.types import ( + multiplier_error as gage_multiplier_error, +) +from google.ads.googleads.v12.errors.types import ( + mutate_error as gage_mutate_error, +) +from google.ads.googleads.v12.errors.types import ( + new_resource_creation_error as gage_new_resource_creation_error, +) +from google.ads.googleads.v12.errors.types import ( + not_allowlisted_error as gage_not_allowlisted_error, +) +from google.ads.googleads.v12.errors.types import ( + not_empty_error as gage_not_empty_error, +) +from google.ads.googleads.v12.errors.types import null_error as gage_null_error +from google.ads.googleads.v12.errors.types import ( + offline_user_data_job_error as gage_offline_user_data_job_error, +) +from google.ads.googleads.v12.errors.types import ( + operation_access_denied_error as gage_operation_access_denied_error, +) +from google.ads.googleads.v12.errors.types import ( + operator_error as gage_operator_error, +) +from google.ads.googleads.v12.errors.types import ( + partial_failure_error as gage_partial_failure_error, +) +from google.ads.googleads.v12.errors.types import ( + payments_account_error as gage_payments_account_error, +) +from google.ads.googleads.v12.errors.types import ( + policy_finding_error as gage_policy_finding_error, +) +from google.ads.googleads.v12.errors.types import ( + policy_validation_parameter_error as gage_policy_validation_parameter_error, +) +from google.ads.googleads.v12.errors.types import ( + policy_violation_error as gage_policy_violation_error, +) +from google.ads.googleads.v12.errors.types import ( + query_error as gage_query_error, +) +from google.ads.googleads.v12.errors.types import ( + quota_error as gage_quota_error, +) +from google.ads.googleads.v12.errors.types import ( + range_error as gage_range_error, +) +from google.ads.googleads.v12.errors.types import ( + reach_plan_error as gage_reach_plan_error, +) +from google.ads.googleads.v12.errors.types import ( + recommendation_error as gage_recommendation_error, +) +from google.ads.googleads.v12.errors.types import ( + region_code_error as gage_region_code_error, +) +from google.ads.googleads.v12.errors.types import ( + request_error as gage_request_error, +) +from google.ads.googleads.v12.errors.types import ( + resource_access_denied_error as gage_resource_access_denied_error, +) +from google.ads.googleads.v12.errors.types import ( + resource_count_limit_exceeded_error as gage_resource_count_limit_exceeded_error, +) +from google.ads.googleads.v12.errors.types import ( + setting_error as gage_setting_error, +) +from google.ads.googleads.v12.errors.types import ( + shared_criterion_error as gage_shared_criterion_error, +) +from google.ads.googleads.v12.errors.types import ( + shared_set_error as gage_shared_set_error, +) +from google.ads.googleads.v12.errors.types import ( + size_limit_error as gage_size_limit_error, +) +from google.ads.googleads.v12.errors.types import ( + smart_campaign_error as gage_smart_campaign_error, +) +from google.ads.googleads.v12.errors.types import ( + string_format_error as gage_string_format_error, +) +from google.ads.googleads.v12.errors.types import ( + string_length_error as gage_string_length_error, +) +from google.ads.googleads.v12.errors.types import ( + third_party_app_analytics_link_error as gage_third_party_app_analytics_link_error, +) +from google.ads.googleads.v12.errors.types import ( + time_zone_error as gage_time_zone_error, +) +from google.ads.googleads.v12.errors.types import ( + url_field_error as gage_url_field_error, +) +from google.ads.googleads.v12.errors.types import ( + user_data_error as gage_user_data_error, +) +from google.ads.googleads.v12.errors.types import ( + user_list_error as gage_user_list_error, +) +from google.ads.googleads.v12.errors.types import ( + youtube_video_registration_error as gage_youtube_video_registration_error, +) +from google.protobuf import duration_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={ + "GoogleAdsFailure", + "GoogleAdsError", + "ErrorCode", + "ErrorLocation", + "ErrorDetails", + "PolicyViolationDetails", + "PolicyFindingDetails", + "QuotaErrorDetails", + "ResourceCountDetails", + }, +) + + +class GoogleAdsFailure(proto.Message): + r"""Describes how a GoogleAds API call failed. It's returned + inside google.rpc.Status.details when a call fails. + + Attributes: + errors (Sequence[google.ads.googleads.v12.errors.types.GoogleAdsError]): + The list of errors that occurred. + request_id (str): + The unique ID of the request that is used for + debugging purposes. + """ + + errors = proto.RepeatedField( + proto.MESSAGE, number=1, message="GoogleAdsError", + ) + request_id = proto.Field(proto.STRING, number=2,) + + +class GoogleAdsError(proto.Message): + r"""GoogleAds-specific error. + + Attributes: + error_code (google.ads.googleads.v12.errors.types.ErrorCode): + An enum value that indicates which error + occurred. + message (str): + A human-readable description of the error. + trigger (google.ads.googleads.v12.common.types.Value): + The value that triggered the error. + location (google.ads.googleads.v12.errors.types.ErrorLocation): + Describes the part of the request proto that + caused the error. + details (google.ads.googleads.v12.errors.types.ErrorDetails): + Additional error details, which are returned + by certain error codes. Most error codes do not + include details. + """ + + error_code = proto.Field(proto.MESSAGE, number=1, message="ErrorCode",) + message = proto.Field(proto.STRING, number=2,) + trigger = proto.Field(proto.MESSAGE, number=3, message=value.Value,) + location = proto.Field(proto.MESSAGE, number=4, message="ErrorLocation",) + details = proto.Field(proto.MESSAGE, number=5, message="ErrorDetails",) + + +class ErrorCode(proto.Message): + r"""The error reason represented by type and enum. + + 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: + request_error (google.ads.googleads.v12.errors.types.RequestErrorEnum.RequestError): + An error caused by the request + + This field is a member of `oneof`_ ``error_code``. + bidding_strategy_error (google.ads.googleads.v12.errors.types.BiddingStrategyErrorEnum.BiddingStrategyError): + An error with a Bidding Strategy mutate. + + This field is a member of `oneof`_ ``error_code``. + url_field_error (google.ads.googleads.v12.errors.types.UrlFieldErrorEnum.UrlFieldError): + An error with a URL field mutate. + + This field is a member of `oneof`_ ``error_code``. + list_operation_error (google.ads.googleads.v12.errors.types.ListOperationErrorEnum.ListOperationError): + An error with a list operation. + + This field is a member of `oneof`_ ``error_code``. + query_error (google.ads.googleads.v12.errors.types.QueryErrorEnum.QueryError): + An error with an AWQL query + + This field is a member of `oneof`_ ``error_code``. + mutate_error (google.ads.googleads.v12.errors.types.MutateErrorEnum.MutateError): + An error with a mutate + + This field is a member of `oneof`_ ``error_code``. + field_mask_error (google.ads.googleads.v12.errors.types.FieldMaskErrorEnum.FieldMaskError): + An error with a field mask + + This field is a member of `oneof`_ ``error_code``. + authorization_error (google.ads.googleads.v12.errors.types.AuthorizationErrorEnum.AuthorizationError): + An error encountered when trying to authorize + a user. + + This field is a member of `oneof`_ ``error_code``. + internal_error (google.ads.googleads.v12.errors.types.InternalErrorEnum.InternalError): + An unexpected server-side error. + + This field is a member of `oneof`_ ``error_code``. + quota_error (google.ads.googleads.v12.errors.types.QuotaErrorEnum.QuotaError): + An error with the amonut of quota remaining. + + This field is a member of `oneof`_ ``error_code``. + ad_error (google.ads.googleads.v12.errors.types.AdErrorEnum.AdError): + An error with an Ad Group Ad mutate. + + This field is a member of `oneof`_ ``error_code``. + ad_group_error (google.ads.googleads.v12.errors.types.AdGroupErrorEnum.AdGroupError): + An error with an Ad Group mutate. + + This field is a member of `oneof`_ ``error_code``. + campaign_budget_error (google.ads.googleads.v12.errors.types.CampaignBudgetErrorEnum.CampaignBudgetError): + An error with a Campaign Budget mutate. + + This field is a member of `oneof`_ ``error_code``. + campaign_error (google.ads.googleads.v12.errors.types.CampaignErrorEnum.CampaignError): + An error with a Campaign mutate. + + This field is a member of `oneof`_ ``error_code``. + authentication_error (google.ads.googleads.v12.errors.types.AuthenticationErrorEnum.AuthenticationError): + Indicates failure to properly authenticate + user. + + This field is a member of `oneof`_ ``error_code``. + ad_group_criterion_customizer_error (google.ads.googleads.v12.errors.types.AdGroupCriterionCustomizerErrorEnum.AdGroupCriterionCustomizerError): + The reasons for the ad group criterion + customizer error. + + This field is a member of `oneof`_ ``error_code``. + ad_group_criterion_error (google.ads.googleads.v12.errors.types.AdGroupCriterionErrorEnum.AdGroupCriterionError): + Indicates failure to properly authenticate + user. + + This field is a member of `oneof`_ ``error_code``. + ad_group_customizer_error (google.ads.googleads.v12.errors.types.AdGroupCustomizerErrorEnum.AdGroupCustomizerError): + The reasons for the ad group customizer + error. + + This field is a member of `oneof`_ ``error_code``. + ad_customizer_error (google.ads.googleads.v12.errors.types.AdCustomizerErrorEnum.AdCustomizerError): + The reasons for the ad customizer error + + This field is a member of `oneof`_ ``error_code``. + ad_group_ad_error (google.ads.googleads.v12.errors.types.AdGroupAdErrorEnum.AdGroupAdError): + The reasons for the ad group ad error + + This field is a member of `oneof`_ ``error_code``. + ad_sharing_error (google.ads.googleads.v12.errors.types.AdSharingErrorEnum.AdSharingError): + The reasons for the ad sharing error + + This field is a member of `oneof`_ ``error_code``. + adx_error (google.ads.googleads.v12.errors.types.AdxErrorEnum.AdxError): + The reasons for the adx error + + This field is a member of `oneof`_ ``error_code``. + asset_error (google.ads.googleads.v12.errors.types.AssetErrorEnum.AssetError): + The reasons for the asset error + + This field is a member of `oneof`_ ``error_code``. + asset_group_asset_error (google.ads.googleads.v12.errors.types.AssetGroupAssetErrorEnum.AssetGroupAssetError): + The reasons for the asset group asset error + + This field is a member of `oneof`_ ``error_code``. + asset_group_listing_group_filter_error (google.ads.googleads.v12.errors.types.AssetGroupListingGroupFilterErrorEnum.AssetGroupListingGroupFilterError): + The reasons for the asset group listing group + filter error + + This field is a member of `oneof`_ ``error_code``. + asset_group_error (google.ads.googleads.v12.errors.types.AssetGroupErrorEnum.AssetGroupError): + The reasons for the asset group error + + This field is a member of `oneof`_ ``error_code``. + asset_set_asset_error (google.ads.googleads.v12.errors.types.AssetSetAssetErrorEnum.AssetSetAssetError): + The reasons for the asset set asset error + + This field is a member of `oneof`_ ``error_code``. + asset_set_link_error (google.ads.googleads.v12.errors.types.AssetSetLinkErrorEnum.AssetSetLinkError): + The reasons for the asset set link error + + This field is a member of `oneof`_ ``error_code``. + asset_set_error (google.ads.googleads.v12.errors.types.AssetSetErrorEnum.AssetSetError): + The reasons for the asset set error + + This field is a member of `oneof`_ ``error_code``. + bidding_error (google.ads.googleads.v12.errors.types.BiddingErrorEnum.BiddingError): + The reasons for the bidding errors + + This field is a member of `oneof`_ ``error_code``. + campaign_criterion_error (google.ads.googleads.v12.errors.types.CampaignCriterionErrorEnum.CampaignCriterionError): + The reasons for the campaign criterion error + + This field is a member of `oneof`_ ``error_code``. + campaign_conversion_goal_error (google.ads.googleads.v12.errors.types.CampaignConversionGoalErrorEnum.CampaignConversionGoalError): + The reasons for the campaign conversion goal + error + + This field is a member of `oneof`_ ``error_code``. + campaign_customizer_error (google.ads.googleads.v12.errors.types.CampaignCustomizerErrorEnum.CampaignCustomizerError): + The reasons for the campaign customizer + error. + + This field is a member of `oneof`_ ``error_code``. + collection_size_error (google.ads.googleads.v12.errors.types.CollectionSizeErrorEnum.CollectionSizeError): + The reasons for the collection size error + + This field is a member of `oneof`_ ``error_code``. + conversion_goal_campaign_config_error (google.ads.googleads.v12.errors.types.ConversionGoalCampaignConfigErrorEnum.ConversionGoalCampaignConfigError): + The reasons for the conversion goal campaign + config error + + This field is a member of `oneof`_ ``error_code``. + country_code_error (google.ads.googleads.v12.errors.types.CountryCodeErrorEnum.CountryCodeError): + The reasons for the country code error + + This field is a member of `oneof`_ ``error_code``. + criterion_error (google.ads.googleads.v12.errors.types.CriterionErrorEnum.CriterionError): + The reasons for the criterion error + + This field is a member of `oneof`_ ``error_code``. + custom_conversion_goal_error (google.ads.googleads.v12.errors.types.CustomConversionGoalErrorEnum.CustomConversionGoalError): + The reasons for the custom conversion goal + error + + This field is a member of `oneof`_ ``error_code``. + customer_customizer_error (google.ads.googleads.v12.errors.types.CustomerCustomizerErrorEnum.CustomerCustomizerError): + The reasons for the customer customizer + error. + + This field is a member of `oneof`_ ``error_code``. + customer_error (google.ads.googleads.v12.errors.types.CustomerErrorEnum.CustomerError): + The reasons for the customer error + + This field is a member of `oneof`_ ``error_code``. + customizer_attribute_error (google.ads.googleads.v12.errors.types.CustomizerAttributeErrorEnum.CustomizerAttributeError): + The reasons for the customizer attribute + error. + + This field is a member of `oneof`_ ``error_code``. + date_error (google.ads.googleads.v12.errors.types.DateErrorEnum.DateError): + The reasons for the date error + + This field is a member of `oneof`_ ``error_code``. + date_range_error (google.ads.googleads.v12.errors.types.DateRangeErrorEnum.DateRangeError): + The reasons for the date range error + + This field is a member of `oneof`_ ``error_code``. + distinct_error (google.ads.googleads.v12.errors.types.DistinctErrorEnum.DistinctError): + The reasons for the distinct error + + This field is a member of `oneof`_ ``error_code``. + feed_attribute_reference_error (google.ads.googleads.v12.errors.types.FeedAttributeReferenceErrorEnum.FeedAttributeReferenceError): + The reasons for the feed attribute reference + error + + This field is a member of `oneof`_ ``error_code``. + function_error (google.ads.googleads.v12.errors.types.FunctionErrorEnum.FunctionError): + The reasons for the function error + + This field is a member of `oneof`_ ``error_code``. + function_parsing_error (google.ads.googleads.v12.errors.types.FunctionParsingErrorEnum.FunctionParsingError): + The reasons for the function parsing error + + This field is a member of `oneof`_ ``error_code``. + id_error (google.ads.googleads.v12.errors.types.IdErrorEnum.IdError): + The reasons for the id error + + This field is a member of `oneof`_ ``error_code``. + image_error (google.ads.googleads.v12.errors.types.ImageErrorEnum.ImageError): + The reasons for the image error + + This field is a member of `oneof`_ ``error_code``. + language_code_error (google.ads.googleads.v12.errors.types.LanguageCodeErrorEnum.LanguageCodeError): + The reasons for the language code error + + This field is a member of `oneof`_ ``error_code``. + media_bundle_error (google.ads.googleads.v12.errors.types.MediaBundleErrorEnum.MediaBundleError): + The reasons for the media bundle error + + This field is a member of `oneof`_ ``error_code``. + media_upload_error (google.ads.googleads.v12.errors.types.MediaUploadErrorEnum.MediaUploadError): + The reasons for media uploading errors. + + This field is a member of `oneof`_ ``error_code``. + media_file_error (google.ads.googleads.v12.errors.types.MediaFileErrorEnum.MediaFileError): + The reasons for the media file error + + This field is a member of `oneof`_ ``error_code``. + merchant_center_error (google.ads.googleads.v12.errors.types.MerchantCenterErrorEnum.MerchantCenterError): + Container for enum describing possible + merchant center errors. + + This field is a member of `oneof`_ ``error_code``. + multiplier_error (google.ads.googleads.v12.errors.types.MultiplierErrorEnum.MultiplierError): + The reasons for the multiplier error + + This field is a member of `oneof`_ ``error_code``. + new_resource_creation_error (google.ads.googleads.v12.errors.types.NewResourceCreationErrorEnum.NewResourceCreationError): + The reasons for the new resource creation + error + + This field is a member of `oneof`_ ``error_code``. + not_empty_error (google.ads.googleads.v12.errors.types.NotEmptyErrorEnum.NotEmptyError): + The reasons for the not empty error + + This field is a member of `oneof`_ ``error_code``. + null_error (google.ads.googleads.v12.errors.types.NullErrorEnum.NullError): + The reasons for the null error + + This field is a member of `oneof`_ ``error_code``. + operator_error (google.ads.googleads.v12.errors.types.OperatorErrorEnum.OperatorError): + The reasons for the operator error + + This field is a member of `oneof`_ ``error_code``. + range_error (google.ads.googleads.v12.errors.types.RangeErrorEnum.RangeError): + The reasons for the range error + + This field is a member of `oneof`_ ``error_code``. + recommendation_error (google.ads.googleads.v12.errors.types.RecommendationErrorEnum.RecommendationError): + The reasons for error in applying a + recommendation + + This field is a member of `oneof`_ ``error_code``. + region_code_error (google.ads.googleads.v12.errors.types.RegionCodeErrorEnum.RegionCodeError): + The reasons for the region code error + + This field is a member of `oneof`_ ``error_code``. + setting_error (google.ads.googleads.v12.errors.types.SettingErrorEnum.SettingError): + The reasons for the setting error + + This field is a member of `oneof`_ ``error_code``. + string_format_error (google.ads.googleads.v12.errors.types.StringFormatErrorEnum.StringFormatError): + The reasons for the string format error + + This field is a member of `oneof`_ ``error_code``. + string_length_error (google.ads.googleads.v12.errors.types.StringLengthErrorEnum.StringLengthError): + The reasons for the string length error + + This field is a member of `oneof`_ ``error_code``. + operation_access_denied_error (google.ads.googleads.v12.errors.types.OperationAccessDeniedErrorEnum.OperationAccessDeniedError): + The reasons for the operation access denied + error + + This field is a member of `oneof`_ ``error_code``. + resource_access_denied_error (google.ads.googleads.v12.errors.types.ResourceAccessDeniedErrorEnum.ResourceAccessDeniedError): + The reasons for the resource access denied + error + + This field is a member of `oneof`_ ``error_code``. + resource_count_limit_exceeded_error (google.ads.googleads.v12.errors.types.ResourceCountLimitExceededErrorEnum.ResourceCountLimitExceededError): + The reasons for the resource count limit + exceeded error + + This field is a member of `oneof`_ ``error_code``. + youtube_video_registration_error (google.ads.googleads.v12.errors.types.YoutubeVideoRegistrationErrorEnum.YoutubeVideoRegistrationError): + The reasons for YouTube video registration + errors. + + This field is a member of `oneof`_ ``error_code``. + ad_group_bid_modifier_error (google.ads.googleads.v12.errors.types.AdGroupBidModifierErrorEnum.AdGroupBidModifierError): + The reasons for the ad group bid modifier + error + + This field is a member of `oneof`_ ``error_code``. + context_error (google.ads.googleads.v12.errors.types.ContextErrorEnum.ContextError): + The reasons for the context error + + This field is a member of `oneof`_ ``error_code``. + field_error (google.ads.googleads.v12.errors.types.FieldErrorEnum.FieldError): + The reasons for the field error + + This field is a member of `oneof`_ ``error_code``. + shared_set_error (google.ads.googleads.v12.errors.types.SharedSetErrorEnum.SharedSetError): + The reasons for the shared set error + + This field is a member of `oneof`_ ``error_code``. + shared_criterion_error (google.ads.googleads.v12.errors.types.SharedCriterionErrorEnum.SharedCriterionError): + The reasons for the shared criterion error + + This field is a member of `oneof`_ ``error_code``. + campaign_shared_set_error (google.ads.googleads.v12.errors.types.CampaignSharedSetErrorEnum.CampaignSharedSetError): + The reasons for the campaign shared set error + + This field is a member of `oneof`_ ``error_code``. + conversion_action_error (google.ads.googleads.v12.errors.types.ConversionActionErrorEnum.ConversionActionError): + The reasons for the conversion action error + + This field is a member of `oneof`_ ``error_code``. + conversion_adjustment_upload_error (google.ads.googleads.v12.errors.types.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError): + The reasons for the conversion adjustment + upload error + + This field is a member of `oneof`_ ``error_code``. + conversion_custom_variable_error (google.ads.googleads.v12.errors.types.ConversionCustomVariableErrorEnum.ConversionCustomVariableError): + The reasons for the conversion custom + variable error + + This field is a member of `oneof`_ ``error_code``. + conversion_upload_error (google.ads.googleads.v12.errors.types.ConversionUploadErrorEnum.ConversionUploadError): + The reasons for the conversion upload error + + This field is a member of `oneof`_ ``error_code``. + conversion_value_rule_error (google.ads.googleads.v12.errors.types.ConversionValueRuleErrorEnum.ConversionValueRuleError): + The reasons for the conversion value rule + error + + This field is a member of `oneof`_ ``error_code``. + conversion_value_rule_set_error (google.ads.googleads.v12.errors.types.ConversionValueRuleSetErrorEnum.ConversionValueRuleSetError): + The reasons for the conversion value rule set + error + + This field is a member of `oneof`_ ``error_code``. + header_error (google.ads.googleads.v12.errors.types.HeaderErrorEnum.HeaderError): + The reasons for the header error. + + This field is a member of `oneof`_ ``error_code``. + database_error (google.ads.googleads.v12.errors.types.DatabaseErrorEnum.DatabaseError): + The reasons for the database error. + + This field is a member of `oneof`_ ``error_code``. + policy_finding_error (google.ads.googleads.v12.errors.types.PolicyFindingErrorEnum.PolicyFindingError): + The reasons for the policy finding error. + + This field is a member of `oneof`_ ``error_code``. + enum_error (google.ads.googleads.v12.errors.types.EnumErrorEnum.EnumError): + The reason for enum error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_error (google.ads.googleads.v12.errors.types.KeywordPlanErrorEnum.KeywordPlanError): + The reason for keyword plan error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_campaign_error (google.ads.googleads.v12.errors.types.KeywordPlanCampaignErrorEnum.KeywordPlanCampaignError): + The reason for keyword plan campaign error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_campaign_keyword_error (google.ads.googleads.v12.errors.types.KeywordPlanCampaignKeywordErrorEnum.KeywordPlanCampaignKeywordError): + The reason for keyword plan campaign keyword + error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_ad_group_error (google.ads.googleads.v12.errors.types.KeywordPlanAdGroupErrorEnum.KeywordPlanAdGroupError): + The reason for keyword plan ad group error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_ad_group_keyword_error (google.ads.googleads.v12.errors.types.KeywordPlanAdGroupKeywordErrorEnum.KeywordPlanAdGroupKeywordError): + The reason for keyword plan ad group keyword + error. + + This field is a member of `oneof`_ ``error_code``. + keyword_plan_idea_error (google.ads.googleads.v12.errors.types.KeywordPlanIdeaErrorEnum.KeywordPlanIdeaError): + The reason for keyword idea error. + + This field is a member of `oneof`_ ``error_code``. + account_budget_proposal_error (google.ads.googleads.v12.errors.types.AccountBudgetProposalErrorEnum.AccountBudgetProposalError): + The reasons for account budget proposal + errors. + + This field is a member of `oneof`_ ``error_code``. + user_list_error (google.ads.googleads.v12.errors.types.UserListErrorEnum.UserListError): + The reasons for the user list error + + This field is a member of `oneof`_ ``error_code``. + change_event_error (google.ads.googleads.v12.errors.types.ChangeEventErrorEnum.ChangeEventError): + The reasons for the change event error + + This field is a member of `oneof`_ ``error_code``. + change_status_error (google.ads.googleads.v12.errors.types.ChangeStatusErrorEnum.ChangeStatusError): + The reasons for the change status error + + This field is a member of `oneof`_ ``error_code``. + feed_error (google.ads.googleads.v12.errors.types.FeedErrorEnum.FeedError): + The reasons for the feed error + + This field is a member of `oneof`_ ``error_code``. + geo_target_constant_suggestion_error (google.ads.googleads.v12.errors.types.GeoTargetConstantSuggestionErrorEnum.GeoTargetConstantSuggestionError): + The reasons for the geo target constant + suggestion error. + + This field is a member of `oneof`_ ``error_code``. + campaign_draft_error (google.ads.googleads.v12.errors.types.CampaignDraftErrorEnum.CampaignDraftError): + The reasons for the campaign draft error + + This field is a member of `oneof`_ ``error_code``. + feed_item_error (google.ads.googleads.v12.errors.types.FeedItemErrorEnum.FeedItemError): + The reasons for the feed item error + + This field is a member of `oneof`_ ``error_code``. + label_error (google.ads.googleads.v12.errors.types.LabelErrorEnum.LabelError): + The reason for the label error. + + This field is a member of `oneof`_ ``error_code``. + billing_setup_error (google.ads.googleads.v12.errors.types.BillingSetupErrorEnum.BillingSetupError): + The reasons for the billing setup error + + This field is a member of `oneof`_ ``error_code``. + customer_client_link_error (google.ads.googleads.v12.errors.types.CustomerClientLinkErrorEnum.CustomerClientLinkError): + The reasons for the customer client link + error + + This field is a member of `oneof`_ ``error_code``. + customer_manager_link_error (google.ads.googleads.v12.errors.types.CustomerManagerLinkErrorEnum.CustomerManagerLinkError): + The reasons for the customer manager link + error + + This field is a member of `oneof`_ ``error_code``. + feed_mapping_error (google.ads.googleads.v12.errors.types.FeedMappingErrorEnum.FeedMappingError): + The reasons for the feed mapping error + + This field is a member of `oneof`_ ``error_code``. + customer_feed_error (google.ads.googleads.v12.errors.types.CustomerFeedErrorEnum.CustomerFeedError): + The reasons for the customer feed error + + This field is a member of `oneof`_ ``error_code``. + ad_group_feed_error (google.ads.googleads.v12.errors.types.AdGroupFeedErrorEnum.AdGroupFeedError): + The reasons for the ad group feed error + + This field is a member of `oneof`_ ``error_code``. + campaign_feed_error (google.ads.googleads.v12.errors.types.CampaignFeedErrorEnum.CampaignFeedError): + The reasons for the campaign feed error + + This field is a member of `oneof`_ ``error_code``. + custom_interest_error (google.ads.googleads.v12.errors.types.CustomInterestErrorEnum.CustomInterestError): + The reasons for the custom interest error + + This field is a member of `oneof`_ ``error_code``. + campaign_experiment_error (google.ads.googleads.v12.errors.types.CampaignExperimentErrorEnum.CampaignExperimentError): + The reasons for the campaign experiment error + + This field is a member of `oneof`_ ``error_code``. + extension_feed_item_error (google.ads.googleads.v12.errors.types.ExtensionFeedItemErrorEnum.ExtensionFeedItemError): + The reasons for the extension feed item error + + This field is a member of `oneof`_ ``error_code``. + ad_parameter_error (google.ads.googleads.v12.errors.types.AdParameterErrorEnum.AdParameterError): + The reasons for the ad parameter error + + This field is a member of `oneof`_ ``error_code``. + feed_item_validation_error (google.ads.googleads.v12.errors.types.FeedItemValidationErrorEnum.FeedItemValidationError): + The reasons for the feed item validation + error + + This field is a member of `oneof`_ ``error_code``. + extension_setting_error (google.ads.googleads.v12.errors.types.ExtensionSettingErrorEnum.ExtensionSettingError): + The reasons for the extension setting error + + This field is a member of `oneof`_ ``error_code``. + feed_item_set_error (google.ads.googleads.v12.errors.types.FeedItemSetErrorEnum.FeedItemSetError): + The reasons for the feed item set error + + This field is a member of `oneof`_ ``error_code``. + feed_item_set_link_error (google.ads.googleads.v12.errors.types.FeedItemSetLinkErrorEnum.FeedItemSetLinkError): + The reasons for the feed item set link error + + This field is a member of `oneof`_ ``error_code``. + feed_item_target_error (google.ads.googleads.v12.errors.types.FeedItemTargetErrorEnum.FeedItemTargetError): + The reasons for the feed item target error + + This field is a member of `oneof`_ ``error_code``. + policy_violation_error (google.ads.googleads.v12.errors.types.PolicyViolationErrorEnum.PolicyViolationError): + The reasons for the policy violation error + + This field is a member of `oneof`_ ``error_code``. + partial_failure_error (google.ads.googleads.v12.errors.types.PartialFailureErrorEnum.PartialFailureError): + The reasons for the mutate job error + + This field is a member of `oneof`_ ``error_code``. + policy_validation_parameter_error (google.ads.googleads.v12.errors.types.PolicyValidationParameterErrorEnum.PolicyValidationParameterError): + The reasons for the policy validation + parameter error + + This field is a member of `oneof`_ ``error_code``. + size_limit_error (google.ads.googleads.v12.errors.types.SizeLimitErrorEnum.SizeLimitError): + The reasons for the size limit error + + This field is a member of `oneof`_ ``error_code``. + offline_user_data_job_error (google.ads.googleads.v12.errors.types.OfflineUserDataJobErrorEnum.OfflineUserDataJobError): + The reasons for the offline user data job + error. + + This field is a member of `oneof`_ ``error_code``. + not_allowlisted_error (google.ads.googleads.v12.errors.types.NotAllowlistedErrorEnum.NotAllowlistedError): + The reasons for the not allowlisted error + + This field is a member of `oneof`_ ``error_code``. + manager_link_error (google.ads.googleads.v12.errors.types.ManagerLinkErrorEnum.ManagerLinkError): + The reasons for the manager link error + + This field is a member of `oneof`_ ``error_code``. + currency_code_error (google.ads.googleads.v12.errors.types.CurrencyCodeErrorEnum.CurrencyCodeError): + The reasons for the currency code error + + This field is a member of `oneof`_ ``error_code``. + experiment_error (google.ads.googleads.v12.errors.types.ExperimentErrorEnum.ExperimentError): + The reasons for the experiment error + + This field is a member of `oneof`_ ``error_code``. + access_invitation_error (google.ads.googleads.v12.errors.types.AccessInvitationErrorEnum.AccessInvitationError): + The reasons for the access invitation error + + This field is a member of `oneof`_ ``error_code``. + reach_plan_error (google.ads.googleads.v12.errors.types.ReachPlanErrorEnum.ReachPlanError): + The reasons for the reach plan error + + This field is a member of `oneof`_ ``error_code``. + invoice_error (google.ads.googleads.v12.errors.types.InvoiceErrorEnum.InvoiceError): + The reasons for the invoice error + + This field is a member of `oneof`_ ``error_code``. + payments_account_error (google.ads.googleads.v12.errors.types.PaymentsAccountErrorEnum.PaymentsAccountError): + The reasons for errors in payments accounts + service + + This field is a member of `oneof`_ ``error_code``. + time_zone_error (google.ads.googleads.v12.errors.types.TimeZoneErrorEnum.TimeZoneError): + The reasons for the time zone error + + This field is a member of `oneof`_ ``error_code``. + asset_link_error (google.ads.googleads.v12.errors.types.AssetLinkErrorEnum.AssetLinkError): + The reasons for the asset link error + + This field is a member of `oneof`_ ``error_code``. + user_data_error (google.ads.googleads.v12.errors.types.UserDataErrorEnum.UserDataError): + The reasons for the user data error. + + This field is a member of `oneof`_ ``error_code``. + batch_job_error (google.ads.googleads.v12.errors.types.BatchJobErrorEnum.BatchJobError): + The reasons for the batch job error + + This field is a member of `oneof`_ ``error_code``. + account_link_error (google.ads.googleads.v12.errors.types.AccountLinkErrorEnum.AccountLinkError): + The reasons for the account link status + change error + + This field is a member of `oneof`_ ``error_code``. + third_party_app_analytics_link_error (google.ads.googleads.v12.errors.types.ThirdPartyAppAnalyticsLinkErrorEnum.ThirdPartyAppAnalyticsLinkError): + The reasons for the third party app analytics + link mutate error + + This field is a member of `oneof`_ ``error_code``. + customer_user_access_error (google.ads.googleads.v12.errors.types.CustomerUserAccessErrorEnum.CustomerUserAccessError): + The reasons for the customer user access + mutate error + + This field is a member of `oneof`_ ``error_code``. + custom_audience_error (google.ads.googleads.v12.errors.types.CustomAudienceErrorEnum.CustomAudienceError): + The reasons for the custom audience error + + This field is a member of `oneof`_ ``error_code``. + audience_error (google.ads.googleads.v12.errors.types.AudienceErrorEnum.AudienceError): + The reasons for the audience error + + This field is a member of `oneof`_ ``error_code``. + smart_campaign_error (google.ads.googleads.v12.errors.types.SmartCampaignErrorEnum.SmartCampaignError): + The reasons for the Smart campaign error + + This field is a member of `oneof`_ ``error_code``. + experiment_arm_error (google.ads.googleads.v12.errors.types.ExperimentArmErrorEnum.ExperimentArmError): + The reasons for the experiment arm error + + This field is a member of `oneof`_ ``error_code``. + audience_insights_error (google.ads.googleads.v12.errors.types.AudienceInsightsErrorEnum.AudienceInsightsError): + The reasons for the Audience Insights error + + This field is a member of `oneof`_ ``error_code``. + """ + + request_error = proto.Field( + proto.ENUM, + number=1, + oneof="error_code", + enum=gage_request_error.RequestErrorEnum.RequestError, + ) + bidding_strategy_error = proto.Field( + proto.ENUM, + number=2, + oneof="error_code", + enum=gage_bidding_strategy_error.BiddingStrategyErrorEnum.BiddingStrategyError, + ) + url_field_error = proto.Field( + proto.ENUM, + number=3, + oneof="error_code", + enum=gage_url_field_error.UrlFieldErrorEnum.UrlFieldError, + ) + list_operation_error = proto.Field( + proto.ENUM, + number=4, + oneof="error_code", + enum=gage_list_operation_error.ListOperationErrorEnum.ListOperationError, + ) + query_error = proto.Field( + proto.ENUM, + number=5, + oneof="error_code", + enum=gage_query_error.QueryErrorEnum.QueryError, + ) + mutate_error = proto.Field( + proto.ENUM, + number=7, + oneof="error_code", + enum=gage_mutate_error.MutateErrorEnum.MutateError, + ) + field_mask_error = proto.Field( + proto.ENUM, + number=8, + oneof="error_code", + enum=gage_field_mask_error.FieldMaskErrorEnum.FieldMaskError, + ) + authorization_error = proto.Field( + proto.ENUM, + number=9, + oneof="error_code", + enum=gage_authorization_error.AuthorizationErrorEnum.AuthorizationError, + ) + internal_error = proto.Field( + proto.ENUM, + number=10, + oneof="error_code", + enum=gage_internal_error.InternalErrorEnum.InternalError, + ) + quota_error = proto.Field( + proto.ENUM, + number=11, + oneof="error_code", + enum=gage_quota_error.QuotaErrorEnum.QuotaError, + ) + ad_error = proto.Field( + proto.ENUM, + number=12, + oneof="error_code", + enum=gage_ad_error.AdErrorEnum.AdError, + ) + ad_group_error = proto.Field( + proto.ENUM, + number=13, + oneof="error_code", + enum=gage_ad_group_error.AdGroupErrorEnum.AdGroupError, + ) + campaign_budget_error = proto.Field( + proto.ENUM, + number=14, + oneof="error_code", + enum=gage_campaign_budget_error.CampaignBudgetErrorEnum.CampaignBudgetError, + ) + campaign_error = proto.Field( + proto.ENUM, + number=15, + oneof="error_code", + enum=gage_campaign_error.CampaignErrorEnum.CampaignError, + ) + authentication_error = proto.Field( + proto.ENUM, + number=17, + oneof="error_code", + enum=gage_authentication_error.AuthenticationErrorEnum.AuthenticationError, + ) + ad_group_criterion_customizer_error = proto.Field( + proto.ENUM, + number=161, + oneof="error_code", + enum=gage_ad_group_criterion_customizer_error.AdGroupCriterionCustomizerErrorEnum.AdGroupCriterionCustomizerError, + ) + ad_group_criterion_error = proto.Field( + proto.ENUM, + number=18, + oneof="error_code", + enum=gage_ad_group_criterion_error.AdGroupCriterionErrorEnum.AdGroupCriterionError, + ) + ad_group_customizer_error = proto.Field( + proto.ENUM, + number=159, + oneof="error_code", + enum=gage_ad_group_customizer_error.AdGroupCustomizerErrorEnum.AdGroupCustomizerError, + ) + ad_customizer_error = proto.Field( + proto.ENUM, + number=19, + oneof="error_code", + enum=gage_ad_customizer_error.AdCustomizerErrorEnum.AdCustomizerError, + ) + ad_group_ad_error = proto.Field( + proto.ENUM, + number=21, + oneof="error_code", + enum=gage_ad_group_ad_error.AdGroupAdErrorEnum.AdGroupAdError, + ) + ad_sharing_error = proto.Field( + proto.ENUM, + number=24, + oneof="error_code", + enum=gage_ad_sharing_error.AdSharingErrorEnum.AdSharingError, + ) + adx_error = proto.Field( + proto.ENUM, + number=25, + oneof="error_code", + enum=gage_adx_error.AdxErrorEnum.AdxError, + ) + asset_error = proto.Field( + proto.ENUM, + number=107, + oneof="error_code", + enum=gage_asset_error.AssetErrorEnum.AssetError, + ) + asset_group_asset_error = proto.Field( + proto.ENUM, + number=149, + oneof="error_code", + enum=gage_asset_group_asset_error.AssetGroupAssetErrorEnum.AssetGroupAssetError, + ) + asset_group_listing_group_filter_error = proto.Field( + proto.ENUM, + number=155, + oneof="error_code", + enum=gage_asset_group_listing_group_filter_error.AssetGroupListingGroupFilterErrorEnum.AssetGroupListingGroupFilterError, + ) + asset_group_error = proto.Field( + proto.ENUM, + number=148, + oneof="error_code", + enum=gage_asset_group_error.AssetGroupErrorEnum.AssetGroupError, + ) + asset_set_asset_error = proto.Field( + proto.ENUM, + number=153, + oneof="error_code", + enum=gage_asset_set_asset_error.AssetSetAssetErrorEnum.AssetSetAssetError, + ) + asset_set_link_error = proto.Field( + proto.ENUM, + number=154, + oneof="error_code", + enum=gage_asset_set_link_error.AssetSetLinkErrorEnum.AssetSetLinkError, + ) + asset_set_error = proto.Field( + proto.ENUM, + number=152, + oneof="error_code", + enum=gage_asset_set_error.AssetSetErrorEnum.AssetSetError, + ) + bidding_error = proto.Field( + proto.ENUM, + number=26, + oneof="error_code", + enum=gage_bidding_error.BiddingErrorEnum.BiddingError, + ) + campaign_criterion_error = proto.Field( + proto.ENUM, + number=29, + oneof="error_code", + enum=gage_campaign_criterion_error.CampaignCriterionErrorEnum.CampaignCriterionError, + ) + campaign_conversion_goal_error = proto.Field( + proto.ENUM, + number=166, + oneof="error_code", + enum=gage_campaign_conversion_goal_error.CampaignConversionGoalErrorEnum.CampaignConversionGoalError, + ) + campaign_customizer_error = proto.Field( + proto.ENUM, + number=160, + oneof="error_code", + enum=gage_campaign_customizer_error.CampaignCustomizerErrorEnum.CampaignCustomizerError, + ) + collection_size_error = proto.Field( + proto.ENUM, + number=31, + oneof="error_code", + enum=gage_collection_size_error.CollectionSizeErrorEnum.CollectionSizeError, + ) + conversion_goal_campaign_config_error = proto.Field( + proto.ENUM, + number=165, + oneof="error_code", + enum=gage_conversion_goal_campaign_config_error.ConversionGoalCampaignConfigErrorEnum.ConversionGoalCampaignConfigError, + ) + country_code_error = proto.Field( + proto.ENUM, + number=109, + oneof="error_code", + enum=gage_country_code_error.CountryCodeErrorEnum.CountryCodeError, + ) + criterion_error = proto.Field( + proto.ENUM, + number=32, + oneof="error_code", + enum=gage_criterion_error.CriterionErrorEnum.CriterionError, + ) + custom_conversion_goal_error = proto.Field( + proto.ENUM, + number=150, + oneof="error_code", + enum=gage_custom_conversion_goal_error.CustomConversionGoalErrorEnum.CustomConversionGoalError, + ) + customer_customizer_error = proto.Field( + proto.ENUM, + number=158, + oneof="error_code", + enum=gage_customer_customizer_error.CustomerCustomizerErrorEnum.CustomerCustomizerError, + ) + customer_error = proto.Field( + proto.ENUM, + number=90, + oneof="error_code", + enum=gage_customer_error.CustomerErrorEnum.CustomerError, + ) + customizer_attribute_error = proto.Field( + proto.ENUM, + number=151, + oneof="error_code", + enum=gage_customizer_attribute_error.CustomizerAttributeErrorEnum.CustomizerAttributeError, + ) + date_error = proto.Field( + proto.ENUM, + number=33, + oneof="error_code", + enum=gage_date_error.DateErrorEnum.DateError, + ) + date_range_error = proto.Field( + proto.ENUM, + number=34, + oneof="error_code", + enum=gage_date_range_error.DateRangeErrorEnum.DateRangeError, + ) + distinct_error = proto.Field( + proto.ENUM, + number=35, + oneof="error_code", + enum=gage_distinct_error.DistinctErrorEnum.DistinctError, + ) + feed_attribute_reference_error = proto.Field( + proto.ENUM, + number=36, + oneof="error_code", + enum=gage_feed_attribute_reference_error.FeedAttributeReferenceErrorEnum.FeedAttributeReferenceError, + ) + function_error = proto.Field( + proto.ENUM, + number=37, + oneof="error_code", + enum=gage_function_error.FunctionErrorEnum.FunctionError, + ) + function_parsing_error = proto.Field( + proto.ENUM, + number=38, + oneof="error_code", + enum=gage_function_parsing_error.FunctionParsingErrorEnum.FunctionParsingError, + ) + id_error = proto.Field( + proto.ENUM, + number=39, + oneof="error_code", + enum=gage_id_error.IdErrorEnum.IdError, + ) + image_error = proto.Field( + proto.ENUM, + number=40, + oneof="error_code", + enum=gage_image_error.ImageErrorEnum.ImageError, + ) + language_code_error = proto.Field( + proto.ENUM, + number=110, + oneof="error_code", + enum=gage_language_code_error.LanguageCodeErrorEnum.LanguageCodeError, + ) + media_bundle_error = proto.Field( + proto.ENUM, + number=42, + oneof="error_code", + enum=gage_media_bundle_error.MediaBundleErrorEnum.MediaBundleError, + ) + media_upload_error = proto.Field( + proto.ENUM, + number=116, + oneof="error_code", + enum=gage_media_upload_error.MediaUploadErrorEnum.MediaUploadError, + ) + media_file_error = proto.Field( + proto.ENUM, + number=86, + oneof="error_code", + enum=gage_media_file_error.MediaFileErrorEnum.MediaFileError, + ) + merchant_center_error = proto.Field( + proto.ENUM, + number=162, + oneof="error_code", + enum=gage_merchant_center_error.MerchantCenterErrorEnum.MerchantCenterError, + ) + multiplier_error = proto.Field( + proto.ENUM, + number=44, + oneof="error_code", + enum=gage_multiplier_error.MultiplierErrorEnum.MultiplierError, + ) + new_resource_creation_error = proto.Field( + proto.ENUM, + number=45, + oneof="error_code", + enum=gage_new_resource_creation_error.NewResourceCreationErrorEnum.NewResourceCreationError, + ) + not_empty_error = proto.Field( + proto.ENUM, + number=46, + oneof="error_code", + enum=gage_not_empty_error.NotEmptyErrorEnum.NotEmptyError, + ) + null_error = proto.Field( + proto.ENUM, + number=47, + oneof="error_code", + enum=gage_null_error.NullErrorEnum.NullError, + ) + operator_error = proto.Field( + proto.ENUM, + number=48, + oneof="error_code", + enum=gage_operator_error.OperatorErrorEnum.OperatorError, + ) + range_error = proto.Field( + proto.ENUM, + number=49, + oneof="error_code", + enum=gage_range_error.RangeErrorEnum.RangeError, + ) + recommendation_error = proto.Field( + proto.ENUM, + number=58, + oneof="error_code", + enum=gage_recommendation_error.RecommendationErrorEnum.RecommendationError, + ) + region_code_error = proto.Field( + proto.ENUM, + number=51, + oneof="error_code", + enum=gage_region_code_error.RegionCodeErrorEnum.RegionCodeError, + ) + setting_error = proto.Field( + proto.ENUM, + number=52, + oneof="error_code", + enum=gage_setting_error.SettingErrorEnum.SettingError, + ) + string_format_error = proto.Field( + proto.ENUM, + number=53, + oneof="error_code", + enum=gage_string_format_error.StringFormatErrorEnum.StringFormatError, + ) + string_length_error = proto.Field( + proto.ENUM, + number=54, + oneof="error_code", + enum=gage_string_length_error.StringLengthErrorEnum.StringLengthError, + ) + operation_access_denied_error = proto.Field( + proto.ENUM, + number=55, + oneof="error_code", + enum=gage_operation_access_denied_error.OperationAccessDeniedErrorEnum.OperationAccessDeniedError, + ) + resource_access_denied_error = proto.Field( + proto.ENUM, + number=56, + oneof="error_code", + enum=gage_resource_access_denied_error.ResourceAccessDeniedErrorEnum.ResourceAccessDeniedError, + ) + resource_count_limit_exceeded_error = proto.Field( + proto.ENUM, + number=57, + oneof="error_code", + enum=gage_resource_count_limit_exceeded_error.ResourceCountLimitExceededErrorEnum.ResourceCountLimitExceededError, + ) + youtube_video_registration_error = proto.Field( + proto.ENUM, + number=117, + oneof="error_code", + enum=gage_youtube_video_registration_error.YoutubeVideoRegistrationErrorEnum.YoutubeVideoRegistrationError, + ) + ad_group_bid_modifier_error = proto.Field( + proto.ENUM, + number=59, + oneof="error_code", + enum=gage_ad_group_bid_modifier_error.AdGroupBidModifierErrorEnum.AdGroupBidModifierError, + ) + context_error = proto.Field( + proto.ENUM, + number=60, + oneof="error_code", + enum=gage_context_error.ContextErrorEnum.ContextError, + ) + field_error = proto.Field( + proto.ENUM, + number=61, + oneof="error_code", + enum=gage_field_error.FieldErrorEnum.FieldError, + ) + shared_set_error = proto.Field( + proto.ENUM, + number=62, + oneof="error_code", + enum=gage_shared_set_error.SharedSetErrorEnum.SharedSetError, + ) + shared_criterion_error = proto.Field( + proto.ENUM, + number=63, + oneof="error_code", + enum=gage_shared_criterion_error.SharedCriterionErrorEnum.SharedCriterionError, + ) + campaign_shared_set_error = proto.Field( + proto.ENUM, + number=64, + oneof="error_code", + enum=gage_campaign_shared_set_error.CampaignSharedSetErrorEnum.CampaignSharedSetError, + ) + conversion_action_error = proto.Field( + proto.ENUM, + number=65, + oneof="error_code", + enum=gage_conversion_action_error.ConversionActionErrorEnum.ConversionActionError, + ) + conversion_adjustment_upload_error = proto.Field( + proto.ENUM, + number=115, + oneof="error_code", + enum=gage_conversion_adjustment_upload_error.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError, + ) + conversion_custom_variable_error = proto.Field( + proto.ENUM, + number=143, + oneof="error_code", + enum=gage_conversion_custom_variable_error.ConversionCustomVariableErrorEnum.ConversionCustomVariableError, + ) + conversion_upload_error = proto.Field( + proto.ENUM, + number=111, + oneof="error_code", + enum=gage_conversion_upload_error.ConversionUploadErrorEnum.ConversionUploadError, + ) + conversion_value_rule_error = proto.Field( + proto.ENUM, + number=145, + oneof="error_code", + enum=gage_conversion_value_rule_error.ConversionValueRuleErrorEnum.ConversionValueRuleError, + ) + conversion_value_rule_set_error = proto.Field( + proto.ENUM, + number=146, + oneof="error_code", + enum=gage_conversion_value_rule_set_error.ConversionValueRuleSetErrorEnum.ConversionValueRuleSetError, + ) + header_error = proto.Field( + proto.ENUM, + number=66, + oneof="error_code", + enum=gage_header_error.HeaderErrorEnum.HeaderError, + ) + database_error = proto.Field( + proto.ENUM, + number=67, + oneof="error_code", + enum=gage_database_error.DatabaseErrorEnum.DatabaseError, + ) + policy_finding_error = proto.Field( + proto.ENUM, + number=68, + oneof="error_code", + enum=gage_policy_finding_error.PolicyFindingErrorEnum.PolicyFindingError, + ) + enum_error = proto.Field( + proto.ENUM, + number=70, + oneof="error_code", + enum=gage_enum_error.EnumErrorEnum.EnumError, + ) + keyword_plan_error = proto.Field( + proto.ENUM, + number=71, + oneof="error_code", + enum=gage_keyword_plan_error.KeywordPlanErrorEnum.KeywordPlanError, + ) + keyword_plan_campaign_error = proto.Field( + proto.ENUM, + number=72, + oneof="error_code", + enum=gage_keyword_plan_campaign_error.KeywordPlanCampaignErrorEnum.KeywordPlanCampaignError, + ) + keyword_plan_campaign_keyword_error = proto.Field( + proto.ENUM, + number=132, + oneof="error_code", + enum=gage_keyword_plan_campaign_keyword_error.KeywordPlanCampaignKeywordErrorEnum.KeywordPlanCampaignKeywordError, + ) + keyword_plan_ad_group_error = proto.Field( + proto.ENUM, + number=74, + oneof="error_code", + enum=gage_keyword_plan_ad_group_error.KeywordPlanAdGroupErrorEnum.KeywordPlanAdGroupError, + ) + keyword_plan_ad_group_keyword_error = proto.Field( + proto.ENUM, + number=133, + oneof="error_code", + enum=gage_keyword_plan_ad_group_keyword_error.KeywordPlanAdGroupKeywordErrorEnum.KeywordPlanAdGroupKeywordError, + ) + keyword_plan_idea_error = proto.Field( + proto.ENUM, + number=76, + oneof="error_code", + enum=gage_keyword_plan_idea_error.KeywordPlanIdeaErrorEnum.KeywordPlanIdeaError, + ) + account_budget_proposal_error = proto.Field( + proto.ENUM, + number=77, + oneof="error_code", + enum=gage_account_budget_proposal_error.AccountBudgetProposalErrorEnum.AccountBudgetProposalError, + ) + user_list_error = proto.Field( + proto.ENUM, + number=78, + oneof="error_code", + enum=gage_user_list_error.UserListErrorEnum.UserListError, + ) + change_event_error = proto.Field( + proto.ENUM, + number=136, + oneof="error_code", + enum=gage_change_event_error.ChangeEventErrorEnum.ChangeEventError, + ) + change_status_error = proto.Field( + proto.ENUM, + number=79, + oneof="error_code", + enum=gage_change_status_error.ChangeStatusErrorEnum.ChangeStatusError, + ) + feed_error = proto.Field( + proto.ENUM, + number=80, + oneof="error_code", + enum=gage_feed_error.FeedErrorEnum.FeedError, + ) + geo_target_constant_suggestion_error = proto.Field( + proto.ENUM, + number=81, + oneof="error_code", + enum=gage_geo_target_constant_suggestion_error.GeoTargetConstantSuggestionErrorEnum.GeoTargetConstantSuggestionError, + ) + campaign_draft_error = proto.Field( + proto.ENUM, + number=82, + oneof="error_code", + enum=gage_campaign_draft_error.CampaignDraftErrorEnum.CampaignDraftError, + ) + feed_item_error = proto.Field( + proto.ENUM, + number=83, + oneof="error_code", + enum=gage_feed_item_error.FeedItemErrorEnum.FeedItemError, + ) + label_error = proto.Field( + proto.ENUM, + number=84, + oneof="error_code", + enum=gage_label_error.LabelErrorEnum.LabelError, + ) + billing_setup_error = proto.Field( + proto.ENUM, + number=87, + oneof="error_code", + enum=gage_billing_setup_error.BillingSetupErrorEnum.BillingSetupError, + ) + customer_client_link_error = proto.Field( + proto.ENUM, + number=88, + oneof="error_code", + enum=gage_customer_client_link_error.CustomerClientLinkErrorEnum.CustomerClientLinkError, + ) + customer_manager_link_error = proto.Field( + proto.ENUM, + number=91, + oneof="error_code", + enum=gage_customer_manager_link_error.CustomerManagerLinkErrorEnum.CustomerManagerLinkError, + ) + feed_mapping_error = proto.Field( + proto.ENUM, + number=92, + oneof="error_code", + enum=gage_feed_mapping_error.FeedMappingErrorEnum.FeedMappingError, + ) + customer_feed_error = proto.Field( + proto.ENUM, + number=93, + oneof="error_code", + enum=gage_customer_feed_error.CustomerFeedErrorEnum.CustomerFeedError, + ) + ad_group_feed_error = proto.Field( + proto.ENUM, + number=94, + oneof="error_code", + enum=gage_ad_group_feed_error.AdGroupFeedErrorEnum.AdGroupFeedError, + ) + campaign_feed_error = proto.Field( + proto.ENUM, + number=96, + oneof="error_code", + enum=gage_campaign_feed_error.CampaignFeedErrorEnum.CampaignFeedError, + ) + custom_interest_error = proto.Field( + proto.ENUM, + number=97, + oneof="error_code", + enum=gage_custom_interest_error.CustomInterestErrorEnum.CustomInterestError, + ) + campaign_experiment_error = proto.Field( + proto.ENUM, + number=98, + oneof="error_code", + enum=gage_campaign_experiment_error.CampaignExperimentErrorEnum.CampaignExperimentError, + ) + extension_feed_item_error = proto.Field( + proto.ENUM, + number=100, + oneof="error_code", + enum=gage_extension_feed_item_error.ExtensionFeedItemErrorEnum.ExtensionFeedItemError, + ) + ad_parameter_error = proto.Field( + proto.ENUM, + number=101, + oneof="error_code", + enum=gage_ad_parameter_error.AdParameterErrorEnum.AdParameterError, + ) + feed_item_validation_error = proto.Field( + proto.ENUM, + number=102, + oneof="error_code", + enum=gage_feed_item_validation_error.FeedItemValidationErrorEnum.FeedItemValidationError, + ) + extension_setting_error = proto.Field( + proto.ENUM, + number=103, + oneof="error_code", + enum=gage_extension_setting_error.ExtensionSettingErrorEnum.ExtensionSettingError, + ) + feed_item_set_error = proto.Field( + proto.ENUM, + number=140, + oneof="error_code", + enum=gage_feed_item_set_error.FeedItemSetErrorEnum.FeedItemSetError, + ) + feed_item_set_link_error = proto.Field( + proto.ENUM, + number=141, + oneof="error_code", + enum=gage_feed_item_set_link_error.FeedItemSetLinkErrorEnum.FeedItemSetLinkError, + ) + feed_item_target_error = proto.Field( + proto.ENUM, + number=104, + oneof="error_code", + enum=gage_feed_item_target_error.FeedItemTargetErrorEnum.FeedItemTargetError, + ) + policy_violation_error = proto.Field( + proto.ENUM, + number=105, + oneof="error_code", + enum=gage_policy_violation_error.PolicyViolationErrorEnum.PolicyViolationError, + ) + partial_failure_error = proto.Field( + proto.ENUM, + number=112, + oneof="error_code", + enum=gage_partial_failure_error.PartialFailureErrorEnum.PartialFailureError, + ) + policy_validation_parameter_error = proto.Field( + proto.ENUM, + number=114, + oneof="error_code", + enum=gage_policy_validation_parameter_error.PolicyValidationParameterErrorEnum.PolicyValidationParameterError, + ) + size_limit_error = proto.Field( + proto.ENUM, + number=118, + oneof="error_code", + enum=gage_size_limit_error.SizeLimitErrorEnum.SizeLimitError, + ) + offline_user_data_job_error = proto.Field( + proto.ENUM, + number=119, + oneof="error_code", + enum=gage_offline_user_data_job_error.OfflineUserDataJobErrorEnum.OfflineUserDataJobError, + ) + not_allowlisted_error = proto.Field( + proto.ENUM, + number=137, + oneof="error_code", + enum=gage_not_allowlisted_error.NotAllowlistedErrorEnum.NotAllowlistedError, + ) + manager_link_error = proto.Field( + proto.ENUM, + number=121, + oneof="error_code", + enum=gage_manager_link_error.ManagerLinkErrorEnum.ManagerLinkError, + ) + currency_code_error = proto.Field( + proto.ENUM, + number=122, + oneof="error_code", + enum=gage_currency_code_error.CurrencyCodeErrorEnum.CurrencyCodeError, + ) + experiment_error = proto.Field( + proto.ENUM, + number=123, + oneof="error_code", + enum=gage_experiment_error.ExperimentErrorEnum.ExperimentError, + ) + access_invitation_error = proto.Field( + proto.ENUM, + number=124, + oneof="error_code", + enum=gage_access_invitation_error.AccessInvitationErrorEnum.AccessInvitationError, + ) + reach_plan_error = proto.Field( + proto.ENUM, + number=125, + oneof="error_code", + enum=gage_reach_plan_error.ReachPlanErrorEnum.ReachPlanError, + ) + invoice_error = proto.Field( + proto.ENUM, + number=126, + oneof="error_code", + enum=gage_invoice_error.InvoiceErrorEnum.InvoiceError, + ) + payments_account_error = proto.Field( + proto.ENUM, + number=127, + oneof="error_code", + enum=gage_payments_account_error.PaymentsAccountErrorEnum.PaymentsAccountError, + ) + time_zone_error = proto.Field( + proto.ENUM, + number=128, + oneof="error_code", + enum=gage_time_zone_error.TimeZoneErrorEnum.TimeZoneError, + ) + asset_link_error = proto.Field( + proto.ENUM, + number=129, + oneof="error_code", + enum=gage_asset_link_error.AssetLinkErrorEnum.AssetLinkError, + ) + user_data_error = proto.Field( + proto.ENUM, + number=130, + oneof="error_code", + enum=gage_user_data_error.UserDataErrorEnum.UserDataError, + ) + batch_job_error = proto.Field( + proto.ENUM, + number=131, + oneof="error_code", + enum=gage_batch_job_error.BatchJobErrorEnum.BatchJobError, + ) + account_link_error = proto.Field( + proto.ENUM, + number=134, + oneof="error_code", + enum=gage_account_link_error.AccountLinkErrorEnum.AccountLinkError, + ) + third_party_app_analytics_link_error = proto.Field( + proto.ENUM, + number=135, + oneof="error_code", + enum=gage_third_party_app_analytics_link_error.ThirdPartyAppAnalyticsLinkErrorEnum.ThirdPartyAppAnalyticsLinkError, + ) + customer_user_access_error = proto.Field( + proto.ENUM, + number=138, + oneof="error_code", + enum=gage_customer_user_access_error.CustomerUserAccessErrorEnum.CustomerUserAccessError, + ) + custom_audience_error = proto.Field( + proto.ENUM, + number=139, + oneof="error_code", + enum=gage_custom_audience_error.CustomAudienceErrorEnum.CustomAudienceError, + ) + audience_error = proto.Field( + proto.ENUM, + number=164, + oneof="error_code", + enum=gage_audience_error.AudienceErrorEnum.AudienceError, + ) + smart_campaign_error = proto.Field( + proto.ENUM, + number=147, + oneof="error_code", + enum=gage_smart_campaign_error.SmartCampaignErrorEnum.SmartCampaignError, + ) + experiment_arm_error = proto.Field( + proto.ENUM, + number=156, + oneof="error_code", + enum=gage_experiment_arm_error.ExperimentArmErrorEnum.ExperimentArmError, + ) + audience_insights_error = proto.Field( + proto.ENUM, + number=167, + oneof="error_code", + enum=gage_audience_insights_error.AudienceInsightsErrorEnum.AudienceInsightsError, + ) + + +class ErrorLocation(proto.Message): + r"""Describes the part of the request proto that caused the + error. + + Attributes: + field_path_elements (Sequence[google.ads.googleads.v12.errors.types.ErrorLocation.FieldPathElement]): + A field path that indicates which field was + invalid in the request. + """ + + class FieldPathElement(proto.Message): + r"""A part of a field path. + + Attributes: + field_name (str): + The name of a field or a oneof + index (int): + If field_name is a repeated field, this is the element that + failed + + This field is a member of `oneof`_ ``_index``. + """ + + field_name = proto.Field(proto.STRING, number=1,) + index = proto.Field(proto.INT32, number=3, optional=True,) + + field_path_elements = proto.RepeatedField( + proto.MESSAGE, number=2, message=FieldPathElement, + ) + + +class ErrorDetails(proto.Message): + r"""Additional error details. + + Attributes: + unpublished_error_code (str): + The error code that should have been + returned, but wasn't. This is used when the + error code is not published in the client + specified version. + policy_violation_details (google.ads.googleads.v12.errors.types.PolicyViolationDetails): + Describes an ad policy violation. + policy_finding_details (google.ads.googleads.v12.errors.types.PolicyFindingDetails): + Describes policy violation findings. + quota_error_details (google.ads.googleads.v12.errors.types.QuotaErrorDetails): + Details on the quota error, including the + scope (account or developer), the rate bucket + name and the retry delay. + resource_count_details (google.ads.googleads.v12.errors.types.ResourceCountDetails): + Details for a resource count limit exceeded + error. + """ + + unpublished_error_code = proto.Field(proto.STRING, number=1,) + policy_violation_details = proto.Field( + proto.MESSAGE, number=2, message="PolicyViolationDetails", + ) + policy_finding_details = proto.Field( + proto.MESSAGE, number=3, message="PolicyFindingDetails", + ) + quota_error_details = proto.Field( + proto.MESSAGE, number=4, message="QuotaErrorDetails", + ) + resource_count_details = proto.Field( + proto.MESSAGE, number=5, message="ResourceCountDetails", + ) + + +class PolicyViolationDetails(proto.Message): + r"""Error returned as part of a mutate response. + This error indicates single policy violation by some text in one + of the fields. + + Attributes: + external_policy_description (str): + Human readable description of policy + violation. + key (google.ads.googleads.v12.common.types.PolicyViolationKey): + Unique identifier for this violation. + If policy is exemptible, this key may be used to + request exemption. + external_policy_name (str): + Human readable name of the policy. + is_exemptible (bool): + Whether user can file an exemption request + for this violation. + """ + + external_policy_description = proto.Field(proto.STRING, number=2,) + key = proto.Field( + proto.MESSAGE, number=4, message=policy.PolicyViolationKey, + ) + external_policy_name = proto.Field(proto.STRING, number=5,) + is_exemptible = proto.Field(proto.BOOL, number=6,) + + +class PolicyFindingDetails(proto.Message): + r"""Error returned as part of a mutate response. + This error indicates one or more policy findings in the fields + of a resource. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + The list of policy topics for the resource. Contains the + PROHIBITED or FULLY_LIMITED policy topic entries that + prevented the resource from being saved (among any other + entries the resource may also have). + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + + +class QuotaErrorDetails(proto.Message): + r"""Additional quota error details when there is QuotaError. + + Attributes: + rate_scope (google.ads.googleads.v12.errors.types.QuotaErrorDetails.QuotaRateScope): + The rate scope of the quota limit. + rate_name (str): + The high level description of the quota + bucket. Examples are "Get requests for standard + access" or "Requests per account". + retry_delay (google.protobuf.duration_pb2.Duration): + Backoff period that customers should wait + before sending next request. + """ + + class QuotaRateScope(proto.Enum): + r"""Enum of possible scopes that quota buckets belong to.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACCOUNT = 2 + DEVELOPER = 3 + + rate_scope = proto.Field(proto.ENUM, number=1, enum=QuotaRateScope,) + rate_name = proto.Field(proto.STRING, number=2,) + retry_delay = proto.Field( + proto.MESSAGE, number=3, message=duration_pb2.Duration, + ) + + +class ResourceCountDetails(proto.Message): + r"""Error details returned when an resource count limit was + exceeded. + + Attributes: + enclosing_id (str): + The ID of the resource whose limit was + exceeded. External customer ID if the limit is + for a customer. + enclosing_resource (str): + The name of the resource (Customer, Campaign + etc.) whose limit was exceeded. + limit (int): + The limit which was exceeded. + limit_type (google.ads.googleads.v12.enums.types.ResourceLimitTypeEnum.ResourceLimitType): + The resource limit type which was exceeded. + existing_count (int): + The count of existing entities. + """ + + enclosing_id = proto.Field(proto.STRING, number=1,) + enclosing_resource = proto.Field(proto.STRING, number=5,) + limit = proto.Field(proto.INT32, number=2,) + limit_type = proto.Field( + proto.ENUM, + number=3, + enum=resource_limit_type.ResourceLimitTypeEnum.ResourceLimitType, + ) + existing_count = proto.Field(proto.INT32, number=4,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/experiment_arm_error.py b/google/ads/googleads/v12/errors/types/experiment_arm_error.py new file mode 100644 index 000000000..0c5c5462c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/experiment_arm_error.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ExperimentArmErrorEnum",}, +) + + +class ExperimentArmErrorEnum(proto.Message): + r"""Container for enum describing possible experiment arm error. + """ + + class ExperimentArmError(proto.Enum): + r"""Enum describing possible experiment arm errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXPERIMENT_ARM_COUNT_LIMIT_EXCEEDED = 2 + INVALID_CAMPAIGN_STATUS = 3 + DUPLICATE_EXPERIMENT_ARM_NAME = 4 + CANNOT_SET_TREATMENT_ARM_CAMPAIGN = 5 + CANNOT_MODIFY_CAMPAIGN_IDS = 6 + CANNOT_MODIFY_CAMPAIGN_WITHOUT_SUFFIX_SET = 7 + CANNOT_MUTATE_TRAFFIC_SPLIT_AFTER_START = 8 + CANNOT_ADD_CAMPAIGN_WITH_SHARED_BUDGET = 9 + CANNOT_ADD_CAMPAIGN_WITH_CUSTOM_BUDGET = 10 + CANNOT_ADD_CAMPAIGNS_WITH_DYNAMIC_ASSETS_ENABLED = 11 + UNSUPPORTED_CAMPAIGN_ADVERTISING_CHANNEL_SUB_TYPE = 12 + CANNOT_ADD_BASE_CAMPAIGN_WITH_DATE_RANGE = 13 + BIDDING_STRATEGY_NOT_SUPPORTED_IN_EXPERIMENTS = 14 + TRAFFIC_SPLIT_NOT_SUPPORTED_FOR_CHANNEL_TYPE = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/experiment_error.py b/google/ads/googleads/v12/errors/types/experiment_error.py new file mode 100644 index 000000000..b452b02a5 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/experiment_error.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ExperimentErrorEnum",}, +) + + +class ExperimentErrorEnum(proto.Message): + r"""Container for enum describing possible experiment error. + """ + + class ExperimentError(proto.Enum): + r"""Enum describing possible experiment errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_SET_START_DATE_IN_PAST = 2 + END_DATE_BEFORE_START_DATE = 3 + START_DATE_TOO_FAR_IN_FUTURE = 4 + DUPLICATE_EXPERIMENT_NAME = 5 + CANNOT_MODIFY_REMOVED_EXPERIMENT = 6 + START_DATE_ALREADY_PASSED = 7 + CANNOT_SET_END_DATE_IN_PAST = 8 + CANNOT_SET_STATUS_TO_REMOVED = 9 + CANNOT_MODIFY_PAST_END_DATE = 10 + INVALID_STATUS = 11 + INVALID_CAMPAIGN_CHANNEL_TYPE = 12 + OVERLAPPING_MEMBERS_AND_DATE_RANGE = 13 + INVALID_TRIAL_ARM_TRAFFIC_SPLIT = 14 + TRAFFIC_SPLIT_OVERLAPPING = 15 + SUM_TRIAL_ARM_TRAFFIC_UNEQUALS_TO_TRIAL_TRAFFIC_SPLIT_DENOMINATOR = 16 + CANNOT_MODIFY_TRAFFIC_SPLIT_AFTER_START = 17 + EXPERIMENT_NOT_FOUND = 18 + EXPERIMENT_NOT_YET_STARTED = 19 + CANNOT_HAVE_MULTIPLE_CONTROL_ARMS = 20 + IN_DESIGN_CAMPAIGNS_NOT_SET = 21 + CANNOT_SET_STATUS_TO_GRADUATED = 22 + CANNOT_CREATE_EXPERIMENT_CAMPAIGN_WITH_SHARED_BUDGET = 23 + CANNOT_CREATE_EXPERIMENT_CAMPAIGN_WITH_CUSTOM_BUDGET = 24 + STATUS_TRANSITION_INVALID = 25 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/extension_feed_item_error.py b/google/ads/googleads/v12/errors/types/extension_feed_item_error.py new file mode 100644 index 000000000..524e9304c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/extension_feed_item_error.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ExtensionFeedItemErrorEnum",}, +) + + +class ExtensionFeedItemErrorEnum(proto.Message): + r"""Container for enum describing possible extension feed item + error. + + """ + + class ExtensionFeedItemError(proto.Enum): + r"""Enum describing possible extension feed item errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + VALUE_OUT_OF_RANGE = 2 + URL_LIST_TOO_LONG = 3 + CANNOT_HAVE_RESTRICTION_ON_EMPTY_GEO_TARGETING = 4 + CANNOT_SET_WITH_FINAL_URLS = 5 + CANNOT_SET_WITHOUT_FINAL_URLS = 6 + INVALID_PHONE_NUMBER = 7 + PHONE_NUMBER_NOT_SUPPORTED_FOR_COUNTRY = 8 + CARRIER_SPECIFIC_SHORT_NUMBER_NOT_ALLOWED = 9 + PREMIUM_RATE_NUMBER_NOT_ALLOWED = 10 + DISALLOWED_NUMBER_TYPE = 11 + INVALID_DOMESTIC_PHONE_NUMBER_FORMAT = 12 + VANITY_PHONE_NUMBER_NOT_ALLOWED = 13 + INVALID_CALL_CONVERSION_ACTION = 14 + CUSTOMER_NOT_ON_ALLOWLIST_FOR_CALLTRACKING = 47 + CALLTRACKING_NOT_SUPPORTED_FOR_COUNTRY = 16 + CUSTOMER_CONSENT_FOR_CALL_RECORDING_REQUIRED = 17 + INVALID_APP_ID = 18 + QUOTES_IN_REVIEW_EXTENSION_SNIPPET = 19 + HYPHENS_IN_REVIEW_EXTENSION_SNIPPET = 20 + REVIEW_EXTENSION_SOURCE_INELIGIBLE = 21 + SOURCE_NAME_IN_REVIEW_EXTENSION_TEXT = 22 + INCONSISTENT_CURRENCY_CODES = 23 + PRICE_EXTENSION_HAS_DUPLICATED_HEADERS = 24 + PRICE_ITEM_HAS_DUPLICATED_HEADER_AND_DESCRIPTION = 25 + PRICE_EXTENSION_HAS_TOO_FEW_ITEMS = 26 + PRICE_EXTENSION_HAS_TOO_MANY_ITEMS = 27 + UNSUPPORTED_VALUE = 28 + UNSUPPORTED_VALUE_IN_SELECTED_LANGUAGE = 29 + INVALID_DEVICE_PREFERENCE = 30 + INVALID_SCHEDULE_END = 31 + DATE_TIME_MUST_BE_IN_ACCOUNT_TIME_ZONE = 32 + INVALID_SNIPPETS_HEADER = 33 + CANNOT_OPERATE_ON_REMOVED_FEED_ITEM = 34 + PHONE_NUMBER_NOT_SUPPORTED_WITH_CALLTRACKING_FOR_COUNTRY = 35 + CONFLICTING_CALL_CONVERSION_SETTINGS = 36 + EXTENSION_TYPE_MISMATCH = 37 + EXTENSION_SUBTYPE_REQUIRED = 38 + EXTENSION_TYPE_UNSUPPORTED = 39 + CANNOT_OPERATE_ON_FEED_WITH_MULTIPLE_MAPPINGS = 40 + CANNOT_OPERATE_ON_FEED_WITH_KEY_ATTRIBUTES = 41 + INVALID_PRICE_FORMAT = 42 + PROMOTION_INVALID_TIME = 43 + TOO_MANY_DECIMAL_PLACES_SPECIFIED = 44 + CONCRETE_EXTENSION_TYPE_REQUIRED = 45 + SCHEDULE_END_NOT_AFTER_START = 46 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/extension_setting_error.py b/google/ads/googleads/v12/errors/types/extension_setting_error.py new file mode 100644 index 000000000..654a3736b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/extension_setting_error.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ExtensionSettingErrorEnum",}, +) + + +class ExtensionSettingErrorEnum(proto.Message): + r"""Container for enum describing validation errors of extension + settings. + + """ + + class ExtensionSettingError(proto.Enum): + r"""Enum describing possible extension setting errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXTENSIONS_REQUIRED = 2 + FEED_TYPE_EXTENSION_TYPE_MISMATCH = 3 + INVALID_FEED_TYPE = 4 + INVALID_FEED_TYPE_FOR_CUSTOMER_EXTENSION_SETTING = 5 + CANNOT_CHANGE_FEED_ITEM_ON_CREATE = 6 + CANNOT_UPDATE_NEWLY_CREATED_EXTENSION = 7 + NO_EXISTING_AD_GROUP_EXTENSION_SETTING_FOR_TYPE = 8 + NO_EXISTING_CAMPAIGN_EXTENSION_SETTING_FOR_TYPE = 9 + NO_EXISTING_CUSTOMER_EXTENSION_SETTING_FOR_TYPE = 10 + AD_GROUP_EXTENSION_SETTING_ALREADY_EXISTS = 11 + CAMPAIGN_EXTENSION_SETTING_ALREADY_EXISTS = 12 + CUSTOMER_EXTENSION_SETTING_ALREADY_EXISTS = 13 + AD_GROUP_FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 14 + CAMPAIGN_FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 15 + CUSTOMER_FEED_ALREADY_EXISTS_FOR_PLACEHOLDER_TYPE = 16 + VALUE_OUT_OF_RANGE = 17 + CANNOT_SET_FIELD_WITH_FINAL_URLS = 18 + FINAL_URLS_NOT_SET = 19 + INVALID_PHONE_NUMBER = 20 + PHONE_NUMBER_NOT_SUPPORTED_FOR_COUNTRY = 21 + CARRIER_SPECIFIC_SHORT_NUMBER_NOT_ALLOWED = 22 + PREMIUM_RATE_NUMBER_NOT_ALLOWED = 23 + DISALLOWED_NUMBER_TYPE = 24 + INVALID_DOMESTIC_PHONE_NUMBER_FORMAT = 25 + VANITY_PHONE_NUMBER_NOT_ALLOWED = 26 + INVALID_COUNTRY_CODE = 27 + INVALID_CALL_CONVERSION_TYPE_ID = 28 + CUSTOMER_NOT_IN_ALLOWLIST_FOR_CALLTRACKING = 69 + CALLTRACKING_NOT_SUPPORTED_FOR_COUNTRY = 30 + INVALID_APP_ID = 31 + QUOTES_IN_REVIEW_EXTENSION_SNIPPET = 32 + HYPHENS_IN_REVIEW_EXTENSION_SNIPPET = 33 + REVIEW_EXTENSION_SOURCE_NOT_ELIGIBLE = 34 + SOURCE_NAME_IN_REVIEW_EXTENSION_TEXT = 35 + MISSING_FIELD = 36 + INCONSISTENT_CURRENCY_CODES = 37 + PRICE_EXTENSION_HAS_DUPLICATED_HEADERS = 38 + PRICE_ITEM_HAS_DUPLICATED_HEADER_AND_DESCRIPTION = 39 + PRICE_EXTENSION_HAS_TOO_FEW_ITEMS = 40 + PRICE_EXTENSION_HAS_TOO_MANY_ITEMS = 41 + UNSUPPORTED_VALUE = 42 + INVALID_DEVICE_PREFERENCE = 43 + INVALID_SCHEDULE_END = 45 + DATE_TIME_MUST_BE_IN_ACCOUNT_TIME_ZONE = 47 + OVERLAPPING_SCHEDULES_NOT_ALLOWED = 48 + SCHEDULE_END_NOT_AFTER_START = 49 + TOO_MANY_SCHEDULES_PER_DAY = 50 + DUPLICATE_EXTENSION_FEED_ITEM_EDIT = 51 + INVALID_SNIPPETS_HEADER = 52 + PHONE_NUMBER_NOT_SUPPORTED_WITH_CALLTRACKING_FOR_COUNTRY = 53 + CAMPAIGN_TARGETING_MISMATCH = 54 + CANNOT_OPERATE_ON_REMOVED_FEED = 55 + EXTENSION_TYPE_REQUIRED = 56 + INCOMPATIBLE_UNDERLYING_MATCHING_FUNCTION = 57 + START_DATE_AFTER_END_DATE = 58 + INVALID_PRICE_FORMAT = 59 + PROMOTION_INVALID_TIME = 60 + PROMOTION_CANNOT_SET_PERCENT_DISCOUNT_AND_MONEY_DISCOUNT = 61 + PROMOTION_CANNOT_SET_PROMOTION_CODE_AND_ORDERS_OVER_AMOUNT = 62 + TOO_MANY_DECIMAL_PLACES_SPECIFIED = 63 + INVALID_LANGUAGE_CODE = 64 + UNSUPPORTED_LANGUAGE = 65 + CUSTOMER_CONSENT_FOR_CALL_RECORDING_REQUIRED = 66 + EXTENSION_SETTING_UPDATE_IS_A_NOOP = 67 + DISALLOWED_TEXT = 68 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_attribute_reference_error.py b/google/ads/googleads/v12/errors/types/feed_attribute_reference_error.py new file mode 100644 index 000000000..cdfcd97ef --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_attribute_reference_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedAttributeReferenceErrorEnum",}, +) + + +class FeedAttributeReferenceErrorEnum(proto.Message): + r"""Container for enum describing possible feed attribute + reference errors. + + """ + + class FeedAttributeReferenceError(proto.Enum): + r"""Enum describing possible feed attribute reference errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_REFERENCE_REMOVED_FEED = 2 + INVALID_FEED_NAME = 3 + INVALID_FEED_ATTRIBUTE_NAME = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_error.py b/google/ads/googleads/v12/errors/types/feed_error.py new file mode 100644 index 000000000..b6bee510e --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_error.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedErrorEnum",}, +) + + +class FeedErrorEnum(proto.Message): + r"""Container for enum describing possible feed errors. + """ + + class FeedError(proto.Enum): + r"""Enum describing possible feed errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ATTRIBUTE_NAMES_NOT_UNIQUE = 2 + ATTRIBUTES_DO_NOT_MATCH_EXISTING_ATTRIBUTES = 3 + CANNOT_SPECIFY_USER_ORIGIN_FOR_SYSTEM_FEED = 4 + CANNOT_SPECIFY_GOOGLE_ORIGIN_FOR_NON_SYSTEM_FEED = 5 + CANNOT_SPECIFY_FEED_ATTRIBUTES_FOR_SYSTEM_FEED = 6 + CANNOT_UPDATE_FEED_ATTRIBUTES_WITH_ORIGIN_GOOGLE = 7 + FEED_REMOVED = 8 + INVALID_ORIGIN_VALUE = 9 + FEED_ORIGIN_IS_NOT_USER = 10 + INVALID_AUTH_TOKEN_FOR_EMAIL = 11 + INVALID_EMAIL = 12 + DUPLICATE_FEED_NAME = 13 + INVALID_FEED_NAME = 14 + MISSING_OAUTH_INFO = 15 + NEW_ATTRIBUTE_CANNOT_BE_PART_OF_UNIQUE_KEY = 16 + TOO_MANY_ATTRIBUTES = 17 + INVALID_BUSINESS_ACCOUNT = 18 + BUSINESS_ACCOUNT_CANNOT_ACCESS_LOCATION_ACCOUNT = 19 + INVALID_AFFILIATE_CHAIN_ID = 20 + DUPLICATE_SYSTEM_FEED = 21 + GMB_ACCESS_ERROR = 22 + CANNOT_HAVE_LOCATION_AND_AFFILIATE_LOCATION_FEEDS = 23 + LEGACY_EXTENSION_TYPE_READ_ONLY = 24 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_item_error.py b/google/ads/googleads/v12/errors/types/feed_item_error.py new file mode 100644 index 000000000..54b169559 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_item_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedItemErrorEnum",}, +) + + +class FeedItemErrorEnum(proto.Message): + r"""Container for enum describing possible feed item errors. + """ + + class FeedItemError(proto.Enum): + r"""Enum describing possible feed item errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_CONVERT_ATTRIBUTE_VALUE_FROM_STRING = 2 + CANNOT_OPERATE_ON_REMOVED_FEED_ITEM = 3 + DATE_TIME_MUST_BE_IN_ACCOUNT_TIME_ZONE = 4 + KEY_ATTRIBUTES_NOT_FOUND = 5 + INVALID_URL = 6 + MISSING_KEY_ATTRIBUTES = 7 + KEY_ATTRIBUTES_NOT_UNIQUE = 8 + CANNOT_MODIFY_KEY_ATTRIBUTE_VALUE = 9 + SIZE_TOO_LARGE_FOR_MULTI_VALUE_ATTRIBUTE = 10 + LEGACY_FEED_TYPE_READ_ONLY = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_item_set_error.py b/google/ads/googleads/v12/errors/types/feed_item_set_error.py new file mode 100644 index 000000000..2d324339a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_item_set_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSetErrorEnum",}, +) + + +class FeedItemSetErrorEnum(proto.Message): + r"""Container for enum describing possible feed item set errors. + """ + + class FeedItemSetError(proto.Enum): + r"""Enum describing possible feed item set errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ITEM_SET_REMOVED = 2 + CANNOT_CLEAR_DYNAMIC_FILTER = 3 + CANNOT_CREATE_DYNAMIC_FILTER = 4 + INVALID_FEED_TYPE = 5 + DUPLICATE_NAME = 6 + WRONG_DYNAMIC_FILTER_FOR_FEED_TYPE = 7 + DYNAMIC_FILTER_INVALID_CHAIN_IDS = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_item_set_link_error.py b/google/ads/googleads/v12/errors/types/feed_item_set_link_error.py new file mode 100644 index 000000000..d3ebcabef --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_item_set_link_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSetLinkErrorEnum",}, +) + + +class FeedItemSetLinkErrorEnum(proto.Message): + r"""Container for enum describing possible feed item set link + errors. + + """ + + class FeedItemSetLinkError(proto.Enum): + r"""Enum describing possible feed item set link errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FEED_ID_MISMATCH = 2 + NO_MUTATE_ALLOWED_FOR_DYNAMIC_SET = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_item_target_error.py b/google/ads/googleads/v12/errors/types/feed_item_target_error.py new file mode 100644 index 000000000..f4a79d561 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_item_target_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedItemTargetErrorEnum",}, +) + + +class FeedItemTargetErrorEnum(proto.Message): + r"""Container for enum describing possible feed item target + errors. + + """ + + class FeedItemTargetError(proto.Enum): + r"""Enum describing possible feed item target errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MUST_SET_TARGET_ONEOF_ON_CREATE = 2 + FEED_ITEM_TARGET_ALREADY_EXISTS = 3 + FEED_ITEM_SCHEDULES_CANNOT_OVERLAP = 4 + TARGET_LIMIT_EXCEEDED_FOR_GIVEN_TYPE = 5 + TOO_MANY_SCHEDULES_PER_DAY = 6 + CANNOT_HAVE_ENABLED_CAMPAIGN_AND_ENABLED_AD_GROUP_TARGETS = 7 + DUPLICATE_AD_SCHEDULE = 8 + DUPLICATE_KEYWORD = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_item_validation_error.py b/google/ads/googleads/v12/errors/types/feed_item_validation_error.py new file mode 100644 index 000000000..ceea7792b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_item_validation_error.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedItemValidationErrorEnum",}, +) + + +class FeedItemValidationErrorEnum(proto.Message): + r"""Container for enum describing possible validation errors of a + feed item. + + """ + + class FeedItemValidationError(proto.Enum): + r"""The possible validation errors of a feed item.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + STRING_TOO_SHORT = 2 + STRING_TOO_LONG = 3 + VALUE_NOT_SPECIFIED = 4 + INVALID_DOMESTIC_PHONE_NUMBER_FORMAT = 5 + INVALID_PHONE_NUMBER = 6 + PHONE_NUMBER_NOT_SUPPORTED_FOR_COUNTRY = 7 + PREMIUM_RATE_NUMBER_NOT_ALLOWED = 8 + DISALLOWED_NUMBER_TYPE = 9 + VALUE_OUT_OF_RANGE = 10 + CALLTRACKING_NOT_SUPPORTED_FOR_COUNTRY = 11 + CUSTOMER_NOT_IN_ALLOWLIST_FOR_CALLTRACKING = 99 + INVALID_COUNTRY_CODE = 13 + INVALID_APP_ID = 14 + MISSING_ATTRIBUTES_FOR_FIELDS = 15 + INVALID_TYPE_ID = 16 + INVALID_EMAIL_ADDRESS = 17 + INVALID_HTTPS_URL = 18 + MISSING_DELIVERY_ADDRESS = 19 + START_DATE_AFTER_END_DATE = 20 + MISSING_FEED_ITEM_START_TIME = 21 + MISSING_FEED_ITEM_END_TIME = 22 + MISSING_FEED_ITEM_ID = 23 + VANITY_PHONE_NUMBER_NOT_ALLOWED = 24 + INVALID_REVIEW_EXTENSION_SNIPPET = 25 + INVALID_NUMBER_FORMAT = 26 + INVALID_DATE_FORMAT = 27 + INVALID_PRICE_FORMAT = 28 + UNKNOWN_PLACEHOLDER_FIELD = 29 + MISSING_ENHANCED_SITELINK_DESCRIPTION_LINE = 30 + REVIEW_EXTENSION_SOURCE_INELIGIBLE = 31 + HYPHENS_IN_REVIEW_EXTENSION_SNIPPET = 32 + DOUBLE_QUOTES_IN_REVIEW_EXTENSION_SNIPPET = 33 + QUOTES_IN_REVIEW_EXTENSION_SNIPPET = 34 + INVALID_FORM_ENCODED_PARAMS = 35 + INVALID_URL_PARAMETER_NAME = 36 + NO_GEOCODING_RESULT = 37 + SOURCE_NAME_IN_REVIEW_EXTENSION_TEXT = 38 + CARRIER_SPECIFIC_SHORT_NUMBER_NOT_ALLOWED = 39 + INVALID_PLACEHOLDER_FIELD_ID = 40 + INVALID_URL_TAG = 41 + LIST_TOO_LONG = 42 + INVALID_ATTRIBUTES_COMBINATION = 43 + DUPLICATE_VALUES = 44 + INVALID_CALL_CONVERSION_ACTION_ID = 45 + CANNOT_SET_WITHOUT_FINAL_URLS = 46 + APP_ID_DOESNT_EXIST_IN_APP_STORE = 47 + INVALID_FINAL_URL = 48 + INVALID_TRACKING_URL = 49 + INVALID_FINAL_URL_FOR_APP_DOWNLOAD_URL = 50 + LIST_TOO_SHORT = 51 + INVALID_USER_ACTION = 52 + INVALID_TYPE_NAME = 53 + INVALID_EVENT_CHANGE_STATUS = 54 + INVALID_SNIPPETS_HEADER = 55 + INVALID_ANDROID_APP_LINK = 56 + NUMBER_TYPE_WITH_CALLTRACKING_NOT_SUPPORTED_FOR_COUNTRY = 57 + RESERVED_KEYWORD_OTHER = 58 + DUPLICATE_OPTION_LABELS = 59 + DUPLICATE_OPTION_PREFILLS = 60 + UNEQUAL_LIST_LENGTHS = 61 + INCONSISTENT_CURRENCY_CODES = 62 + PRICE_EXTENSION_HAS_DUPLICATED_HEADERS = 63 + ITEM_HAS_DUPLICATED_HEADER_AND_DESCRIPTION = 64 + PRICE_EXTENSION_HAS_TOO_FEW_ITEMS = 65 + UNSUPPORTED_VALUE = 66 + INVALID_FINAL_MOBILE_URL = 67 + INVALID_KEYWORDLESS_AD_RULE_LABEL = 68 + VALUE_TRACK_PARAMETER_NOT_SUPPORTED = 69 + UNSUPPORTED_VALUE_IN_SELECTED_LANGUAGE = 70 + INVALID_IOS_APP_LINK = 71 + MISSING_IOS_APP_LINK_OR_IOS_APP_STORE_ID = 72 + PROMOTION_INVALID_TIME = 73 + PROMOTION_CANNOT_SET_PERCENT_OFF_AND_MONEY_AMOUNT_OFF = 74 + PROMOTION_CANNOT_SET_PROMOTION_CODE_AND_ORDERS_OVER_AMOUNT = 75 + TOO_MANY_DECIMAL_PLACES_SPECIFIED = 76 + AD_CUSTOMIZERS_NOT_ALLOWED = 77 + INVALID_LANGUAGE_CODE = 78 + UNSUPPORTED_LANGUAGE = 79 + IF_FUNCTION_NOT_ALLOWED = 80 + INVALID_FINAL_URL_SUFFIX = 81 + INVALID_TAG_IN_FINAL_URL_SUFFIX = 82 + INVALID_FINAL_URL_SUFFIX_FORMAT = 83 + CUSTOMER_CONSENT_FOR_CALL_RECORDING_REQUIRED = 84 + ONLY_ONE_DELIVERY_OPTION_IS_ALLOWED = 85 + NO_DELIVERY_OPTION_IS_SET = 86 + INVALID_CONVERSION_REPORTING_STATE = 87 + IMAGE_SIZE_WRONG = 88 + EMAIL_DELIVERY_NOT_AVAILABLE_IN_COUNTRY = 89 + AUTO_REPLY_NOT_AVAILABLE_IN_COUNTRY = 90 + INVALID_LATITUDE_VALUE = 91 + INVALID_LONGITUDE_VALUE = 92 + TOO_MANY_LABELS = 93 + INVALID_IMAGE_URL = 94 + MISSING_LATITUDE_VALUE = 95 + MISSING_LONGITUDE_VALUE = 96 + ADDRESS_NOT_FOUND = 97 + ADDRESS_NOT_TARGETABLE = 98 + INVALID_ASSET_ID = 100 + INCOMPATIBLE_ASSET_TYPE = 101 + IMAGE_ERROR_UNEXPECTED_SIZE = 102 + IMAGE_ERROR_ASPECT_RATIO_NOT_ALLOWED = 103 + IMAGE_ERROR_FILE_TOO_LARGE = 104 + IMAGE_ERROR_FORMAT_NOT_ALLOWED = 105 + IMAGE_ERROR_CONSTRAINTS_VIOLATED = 106 + IMAGE_ERROR_SERVER_ERROR = 107 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/feed_mapping_error.py b/google/ads/googleads/v12/errors/types/feed_mapping_error.py new file mode 100644 index 000000000..73954a8c5 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/feed_mapping_error.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FeedMappingErrorEnum",}, +) + + +class FeedMappingErrorEnum(proto.Message): + r"""Container for enum describing possible feed item errors. + """ + + class FeedMappingError(proto.Enum): + r"""Enum describing possible feed item errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_PLACEHOLDER_FIELD = 2 + INVALID_CRITERION_FIELD = 3 + INVALID_PLACEHOLDER_TYPE = 4 + INVALID_CRITERION_TYPE = 5 + NO_ATTRIBUTE_FIELD_MAPPINGS = 7 + FEED_ATTRIBUTE_TYPE_MISMATCH = 8 + CANNOT_OPERATE_ON_MAPPINGS_FOR_SYSTEM_GENERATED_FEED = 9 + MULTIPLE_MAPPINGS_FOR_PLACEHOLDER_TYPE = 10 + MULTIPLE_MAPPINGS_FOR_CRITERION_TYPE = 11 + MULTIPLE_MAPPINGS_FOR_PLACEHOLDER_FIELD = 12 + MULTIPLE_MAPPINGS_FOR_CRITERION_FIELD = 13 + UNEXPECTED_ATTRIBUTE_FIELD_MAPPINGS = 14 + LOCATION_PLACEHOLDER_ONLY_FOR_PLACES_FEEDS = 15 + CANNOT_MODIFY_MAPPINGS_FOR_TYPED_FEED = 16 + INVALID_PLACEHOLDER_TYPE_FOR_NON_SYSTEM_GENERATED_FEED = 17 + INVALID_PLACEHOLDER_TYPE_FOR_SYSTEM_GENERATED_FEED_TYPE = 18 + ATTRIBUTE_FIELD_MAPPING_MISSING_FIELD = 19 + LEGACY_FEED_TYPE_READ_ONLY = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/field_error.py b/google/ads/googleads/v12/errors/types/field_error.py new file mode 100644 index 000000000..755e5f763 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/field_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FieldErrorEnum",}, +) + + +class FieldErrorEnum(proto.Message): + r"""Container for enum describing possible field errors. + """ + + class FieldError(proto.Enum): + r"""Enum describing possible field errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REQUIRED = 2 + IMMUTABLE_FIELD = 3 + INVALID_VALUE = 4 + VALUE_MUST_BE_UNSET = 5 + REQUIRED_NONEMPTY_LIST = 6 + FIELD_CANNOT_BE_CLEARED = 7 + BLOCKED_VALUE = 9 + FIELD_CAN_ONLY_BE_CLEARED = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/field_mask_error.py b/google/ads/googleads/v12/errors/types/field_mask_error.py new file mode 100644 index 000000000..3f2a25ab1 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/field_mask_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FieldMaskErrorEnum",}, +) + + +class FieldMaskErrorEnum(proto.Message): + r"""Container for enum describing possible field mask errors. + """ + + class FieldMaskError(proto.Enum): + r"""Enum describing possible field mask errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FIELD_MASK_MISSING = 5 + FIELD_MASK_NOT_ALLOWED = 4 + FIELD_NOT_FOUND = 2 + FIELD_HAS_SUBFIELDS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/function_error.py b/google/ads/googleads/v12/errors/types/function_error.py new file mode 100644 index 000000000..8f33c82fe --- /dev/null +++ b/google/ads/googleads/v12/errors/types/function_error.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FunctionErrorEnum",}, +) + + +class FunctionErrorEnum(proto.Message): + r"""Container for enum describing possible function errors. + """ + + class FunctionError(proto.Enum): + r"""Enum describing possible function errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_FUNCTION_FORMAT = 2 + DATA_TYPE_MISMATCH = 3 + INVALID_CONJUNCTION_OPERANDS = 4 + INVALID_NUMBER_OF_OPERANDS = 5 + INVALID_OPERAND_TYPE = 6 + INVALID_OPERATOR = 7 + INVALID_REQUEST_CONTEXT_TYPE = 8 + INVALID_FUNCTION_FOR_CALL_PLACEHOLDER = 9 + INVALID_FUNCTION_FOR_PLACEHOLDER = 10 + INVALID_OPERAND = 11 + MISSING_CONSTANT_OPERAND_VALUE = 12 + INVALID_CONSTANT_OPERAND_VALUE = 13 + INVALID_NESTING = 14 + MULTIPLE_FEED_IDS_NOT_SUPPORTED = 15 + INVALID_FUNCTION_FOR_FEED_WITH_FIXED_SCHEMA = 16 + INVALID_ATTRIBUTE_NAME = 17 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/function_parsing_error.py b/google/ads/googleads/v12/errors/types/function_parsing_error.py new file mode 100644 index 000000000..49b0c1fc9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/function_parsing_error.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"FunctionParsingErrorEnum",}, +) + + +class FunctionParsingErrorEnum(proto.Message): + r"""Container for enum describing possible function parsing + errors. + + """ + + class FunctionParsingError(proto.Enum): + r"""Enum describing possible function parsing errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_MORE_INPUT = 2 + EXPECTED_CHARACTER = 3 + UNEXPECTED_SEPARATOR = 4 + UNMATCHED_LEFT_BRACKET = 5 + UNMATCHED_RIGHT_BRACKET = 6 + TOO_MANY_NESTED_FUNCTIONS = 7 + MISSING_RIGHT_HAND_OPERAND = 8 + INVALID_OPERATOR_NAME = 9 + FEED_ATTRIBUTE_OPERAND_ARGUMENT_NOT_INTEGER = 10 + NO_OPERANDS = 11 + TOO_MANY_OPERANDS = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/geo_target_constant_suggestion_error.py b/google/ads/googleads/v12/errors/types/geo_target_constant_suggestion_error.py new file mode 100644 index 000000000..e6ca0e5f6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/geo_target_constant_suggestion_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"GeoTargetConstantSuggestionErrorEnum",}, +) + + +class GeoTargetConstantSuggestionErrorEnum(proto.Message): + r"""Container for enum describing possible geo target constant + suggestion errors. + + """ + + class GeoTargetConstantSuggestionError(proto.Enum): + r"""Enum describing possible geo target constant suggestion + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + LOCATION_NAME_SIZE_LIMIT = 2 + LOCATION_NAME_LIMIT = 3 + INVALID_COUNTRY_CODE = 4 + REQUEST_PARAMETERS_UNSET = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/header_error.py b/google/ads/googleads/v12/errors/types/header_error.py new file mode 100644 index 000000000..a0ffad9c7 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/header_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"HeaderErrorEnum",}, +) + + +class HeaderErrorEnum(proto.Message): + r"""Container for enum describing possible header errors. + """ + + class HeaderError(proto.Enum): + r"""Enum describing possible header errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_LOGIN_CUSTOMER_ID = 3 + INVALID_LINKED_CUSTOMER_ID = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/id_error.py b/google/ads/googleads/v12/errors/types/id_error.py new file mode 100644 index 000000000..d37186790 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/id_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"IdErrorEnum",}, +) + + +class IdErrorEnum(proto.Message): + r"""Container for enum describing possible ID errors. + """ + + class IdError(proto.Enum): + r"""Enum describing possible ID errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_FOUND = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/image_error.py b/google/ads/googleads/v12/errors/types/image_error.py new file mode 100644 index 000000000..6662cf89f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/image_error.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ImageErrorEnum",}, +) + + +class ImageErrorEnum(proto.Message): + r"""Container for enum describing possible image errors. + """ + + class ImageError(proto.Enum): + r"""Enum describing possible image errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_IMAGE = 2 + STORAGE_ERROR = 3 + BAD_REQUEST = 4 + UNEXPECTED_SIZE = 5 + ANIMATED_NOT_ALLOWED = 6 + ANIMATION_TOO_LONG = 7 + SERVER_ERROR = 8 + CMYK_JPEG_NOT_ALLOWED = 9 + FLASH_NOT_ALLOWED = 10 + FLASH_WITHOUT_CLICKTAG = 11 + FLASH_ERROR_AFTER_FIXING_CLICK_TAG = 12 + ANIMATED_VISUAL_EFFECT = 13 + FLASH_ERROR = 14 + LAYOUT_PROBLEM = 15 + PROBLEM_READING_IMAGE_FILE = 16 + ERROR_STORING_IMAGE = 17 + ASPECT_RATIO_NOT_ALLOWED = 18 + FLASH_HAS_NETWORK_OBJECTS = 19 + FLASH_HAS_NETWORK_METHODS = 20 + FLASH_HAS_URL = 21 + FLASH_HAS_MOUSE_TRACKING = 22 + FLASH_HAS_RANDOM_NUM = 23 + FLASH_SELF_TARGETS = 24 + FLASH_BAD_GETURL_TARGET = 25 + FLASH_VERSION_NOT_SUPPORTED = 26 + FLASH_WITHOUT_HARD_CODED_CLICK_URL = 27 + INVALID_FLASH_FILE = 28 + FAILED_TO_FIX_CLICK_TAG_IN_FLASH = 29 + FLASH_ACCESSES_NETWORK_RESOURCES = 30 + FLASH_EXTERNAL_JS_CALL = 31 + FLASH_EXTERNAL_FS_CALL = 32 + FILE_TOO_LARGE = 33 + IMAGE_DATA_TOO_LARGE = 34 + IMAGE_PROCESSING_ERROR = 35 + IMAGE_TOO_SMALL = 36 + INVALID_INPUT = 37 + PROBLEM_READING_FILE = 38 + IMAGE_CONSTRAINTS_VIOLATED = 39 + FORMAT_NOT_ALLOWED = 40 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/internal_error.py b/google/ads/googleads/v12/errors/types/internal_error.py new file mode 100644 index 000000000..da244525d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/internal_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"InternalErrorEnum",}, +) + + +class InternalErrorEnum(proto.Message): + r"""Container for enum describing possible internal errors. + """ + + class InternalError(proto.Enum): + r"""Enum describing possible internal errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INTERNAL_ERROR = 2 + ERROR_CODE_NOT_PUBLISHED = 3 + TRANSIENT_ERROR = 4 + DEADLINE_EXCEEDED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/invoice_error.py b/google/ads/googleads/v12/errors/types/invoice_error.py new file mode 100644 index 000000000..112f1bff7 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/invoice_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"InvoiceErrorEnum",}, +) + + +class InvoiceErrorEnum(proto.Message): + r"""Container for enum describing possible invoice errors. + """ + + class InvoiceError(proto.Enum): + r"""Enum describing possible invoice errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + YEAR_MONTH_TOO_OLD = 2 + NOT_INVOICED_CUSTOMER = 3 + BILLING_SETUP_NOT_APPROVED = 4 + BILLING_SETUP_NOT_ON_MONTHLY_INVOICING = 5 + NON_SERVING_CUSTOMER = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_error.py new file mode 100644 index 000000000..235f74ecf --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_error.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanAdGroupErrorEnum",}, +) + + +class KeywordPlanAdGroupErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying a + keyword plan ad group. + + """ + + class KeywordPlanAdGroupError(proto.Enum): + r"""Enum describing possible errors from applying a keyword plan + ad group. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_NAME = 2 + DUPLICATE_NAME = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_keyword_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_keyword_error.py new file mode 100644 index 000000000..2b1936a65 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_ad_group_keyword_error.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanAdGroupKeywordErrorEnum",}, +) + + +class KeywordPlanAdGroupKeywordErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying + an ad group keyword or a campaign keyword from a keyword plan. + + """ + + class KeywordPlanAdGroupKeywordError(proto.Enum): + r"""Enum describing possible errors from applying a keyword plan + ad group keyword or keyword plan campaign keyword. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_KEYWORD_MATCH_TYPE = 2 + DUPLICATE_KEYWORD = 3 + KEYWORD_TEXT_TOO_LONG = 4 + KEYWORD_HAS_INVALID_CHARS = 5 + KEYWORD_HAS_TOO_MANY_WORDS = 6 + INVALID_KEYWORD_TEXT = 7 + NEGATIVE_KEYWORD_HAS_CPC_BID = 8 + NEW_BMM_KEYWORDS_NOT_ALLOWED = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_campaign_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_campaign_error.py new file mode 100644 index 000000000..c34306971 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_campaign_error.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanCampaignErrorEnum",}, +) + + +class KeywordPlanCampaignErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying a + keyword plan campaign. + + """ + + class KeywordPlanCampaignError(proto.Enum): + r"""Enum describing possible errors from applying a keyword plan + campaign. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_NAME = 2 + INVALID_LANGUAGES = 3 + INVALID_GEOS = 4 + DUPLICATE_NAME = 5 + MAX_GEOS_EXCEEDED = 6 + MAX_LANGUAGES_EXCEEDED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_campaign_keyword_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_campaign_keyword_error.py new file mode 100644 index 000000000..67d8eda17 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_campaign_keyword_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanCampaignKeywordErrorEnum",}, +) + + +class KeywordPlanCampaignKeywordErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying a + keyword plan campaign keyword. + + """ + + class KeywordPlanCampaignKeywordError(proto.Enum): + r"""Enum describing possible errors from applying a keyword plan + campaign keyword. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + CAMPAIGN_KEYWORD_IS_POSITIVE = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_error.py new file mode 100644 index 000000000..210824df6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_error.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanErrorEnum",}, +) + + +class KeywordPlanErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying a + keyword plan resource (keyword plan, keyword plan campaign, + keyword plan ad group or keyword plan keyword) or + KeywordPlanService RPC. + + """ + + class KeywordPlanError(proto.Enum): + r"""Enum describing possible errors from applying a keyword plan.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BID_MULTIPLIER_OUT_OF_RANGE = 2 + BID_TOO_HIGH = 3 + BID_TOO_LOW = 4 + BID_TOO_MANY_FRACTIONAL_DIGITS = 5 + DAILY_BUDGET_TOO_LOW = 6 + DAILY_BUDGET_TOO_MANY_FRACTIONAL_DIGITS = 7 + INVALID_VALUE = 8 + KEYWORD_PLAN_HAS_NO_KEYWORDS = 9 + KEYWORD_PLAN_NOT_ENABLED = 10 + KEYWORD_PLAN_NOT_FOUND = 11 + MISSING_BID = 13 + MISSING_FORECAST_PERIOD = 14 + INVALID_FORECAST_DATE_RANGE = 15 + INVALID_NAME = 16 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/keyword_plan_idea_error.py b/google/ads/googleads/v12/errors/types/keyword_plan_idea_error.py new file mode 100644 index 000000000..ebad246ad --- /dev/null +++ b/google/ads/googleads/v12/errors/types/keyword_plan_idea_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanIdeaErrorEnum",}, +) + + +class KeywordPlanIdeaErrorEnum(proto.Message): + r"""Container for enum describing possible errors from + KeywordPlanIdeaService. + + """ + + class KeywordPlanIdeaError(proto.Enum): + r"""Enum describing possible errors from KeywordPlanIdeaService.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + URL_CRAWL_ERROR = 2 + INVALID_VALUE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/label_error.py b/google/ads/googleads/v12/errors/types/label_error.py new file mode 100644 index 000000000..3342b9b04 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/label_error.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"LabelErrorEnum",}, +) + + +class LabelErrorEnum(proto.Message): + r"""Container for enum describing possible label errors. + """ + + class LabelError(proto.Enum): + r"""Enum describing possible label errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_APPLY_INACTIVE_LABEL = 2 + CANNOT_APPLY_LABEL_TO_DISABLED_AD_GROUP_CRITERION = 3 + CANNOT_APPLY_LABEL_TO_NEGATIVE_AD_GROUP_CRITERION = 4 + EXCEEDED_LABEL_LIMIT_PER_TYPE = 5 + INVALID_RESOURCE_FOR_MANAGER_LABEL = 6 + DUPLICATE_NAME = 7 + INVALID_LABEL_NAME = 8 + CANNOT_ATTACH_LABEL_TO_DRAFT = 9 + CANNOT_ATTACH_NON_MANAGER_LABEL_TO_CUSTOMER = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/language_code_error.py b/google/ads/googleads/v12/errors/types/language_code_error.py new file mode 100644 index 000000000..51cb755c6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/language_code_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"LanguageCodeErrorEnum",}, +) + + +class LanguageCodeErrorEnum(proto.Message): + r"""Container for enum describing language code errors. + """ + + class LanguageCodeError(proto.Enum): + r"""Enum describing language code errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + LANGUAGE_CODE_NOT_FOUND = 2 + INVALID_LANGUAGE_CODE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/list_operation_error.py b/google/ads/googleads/v12/errors/types/list_operation_error.py new file mode 100644 index 000000000..5ba751564 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/list_operation_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ListOperationErrorEnum",}, +) + + +class ListOperationErrorEnum(proto.Message): + r"""Container for enum describing possible list operation errors. + """ + + class ListOperationError(proto.Enum): + r"""Enum describing possible list operation errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REQUIRED_FIELD_MISSING = 7 + DUPLICATE_VALUES = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/manager_link_error.py b/google/ads/googleads/v12/errors/types/manager_link_error.py new file mode 100644 index 000000000..e5853386b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/manager_link_error.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ManagerLinkErrorEnum",}, +) + + +class ManagerLinkErrorEnum(proto.Message): + r"""Container for enum describing possible ManagerLink errors. + """ + + class ManagerLinkError(proto.Enum): + r"""Enum describing possible ManagerLink errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACCOUNTS_NOT_COMPATIBLE_FOR_LINKING = 2 + TOO_MANY_MANAGERS = 3 + TOO_MANY_INVITES = 4 + ALREADY_INVITED_BY_THIS_MANAGER = 5 + ALREADY_MANAGED_BY_THIS_MANAGER = 6 + ALREADY_MANAGED_IN_HIERARCHY = 7 + DUPLICATE_CHILD_FOUND = 8 + CLIENT_HAS_NO_ADMIN_USER = 9 + MAX_DEPTH_EXCEEDED = 10 + CYCLE_NOT_ALLOWED = 11 + TOO_MANY_ACCOUNTS = 12 + TOO_MANY_ACCOUNTS_AT_MANAGER = 13 + NON_OWNER_USER_CANNOT_MODIFY_LINK = 14 + SUSPENDED_ACCOUNT_CANNOT_ADD_CLIENTS = 15 + CLIENT_OUTSIDE_TREE = 16 + INVALID_STATUS_CHANGE = 17 + INVALID_CHANGE = 18 + CUSTOMER_CANNOT_MANAGE_SELF = 19 + CREATING_ENABLED_LINK_NOT_ALLOWED = 20 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/media_bundle_error.py b/google/ads/googleads/v12/errors/types/media_bundle_error.py new file mode 100644 index 000000000..91e2efaf9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/media_bundle_error.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MediaBundleErrorEnum",}, +) + + +class MediaBundleErrorEnum(proto.Message): + r"""Container for enum describing possible media bundle errors. + """ + + class MediaBundleError(proto.Enum): + r"""Enum describing possible media bundle errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + BAD_REQUEST = 3 + DOUBLECLICK_BUNDLE_NOT_ALLOWED = 4 + EXTERNAL_URL_NOT_ALLOWED = 5 + FILE_TOO_LARGE = 6 + GOOGLE_WEB_DESIGNER_ZIP_FILE_NOT_PUBLISHED = 7 + INVALID_INPUT = 8 + INVALID_MEDIA_BUNDLE = 9 + INVALID_MEDIA_BUNDLE_ENTRY = 10 + INVALID_MIME_TYPE = 11 + INVALID_PATH = 12 + INVALID_URL_REFERENCE = 13 + MEDIA_DATA_TOO_LARGE = 14 + MISSING_PRIMARY_MEDIA_BUNDLE_ENTRY = 15 + SERVER_ERROR = 16 + STORAGE_ERROR = 17 + SWIFFY_BUNDLE_NOT_ALLOWED = 18 + TOO_MANY_FILES = 19 + UNEXPECTED_SIZE = 20 + UNSUPPORTED_GOOGLE_WEB_DESIGNER_ENVIRONMENT = 21 + UNSUPPORTED_HTML5_FEATURE = 22 + URL_IN_MEDIA_BUNDLE_NOT_SSL_COMPLIANT = 23 + CUSTOM_EXIT_NOT_ALLOWED = 24 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/media_file_error.py b/google/ads/googleads/v12/errors/types/media_file_error.py new file mode 100644 index 000000000..90b5b347f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/media_file_error.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MediaFileErrorEnum",}, +) + + +class MediaFileErrorEnum(proto.Message): + r"""Container for enum describing possible media file errors. + """ + + class MediaFileError(proto.Enum): + r"""Enum describing possible media file errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_CREATE_STANDARD_ICON = 2 + CANNOT_SELECT_STANDARD_ICON_WITH_OTHER_TYPES = 3 + CANNOT_SPECIFY_MEDIA_FILE_ID_AND_DATA = 4 + DUPLICATE_MEDIA = 5 + EMPTY_FIELD = 6 + RESOURCE_REFERENCED_IN_MULTIPLE_OPS = 7 + FIELD_NOT_SUPPORTED_FOR_MEDIA_SUB_TYPE = 8 + INVALID_MEDIA_FILE_ID = 9 + INVALID_MEDIA_SUB_TYPE = 10 + INVALID_MEDIA_FILE_TYPE = 11 + INVALID_MIME_TYPE = 12 + INVALID_REFERENCE_ID = 13 + INVALID_YOU_TUBE_ID = 14 + MEDIA_FILE_FAILED_TRANSCODING = 15 + MEDIA_NOT_TRANSCODED = 16 + MEDIA_TYPE_DOES_NOT_MATCH_MEDIA_FILE_TYPE = 17 + NO_FIELDS_SPECIFIED = 18 + NULL_REFERENCE_ID_AND_MEDIA_ID = 19 + TOO_LONG = 20 + UNSUPPORTED_TYPE = 21 + YOU_TUBE_SERVICE_UNAVAILABLE = 22 + YOU_TUBE_VIDEO_HAS_NON_POSITIVE_DURATION = 23 + YOU_TUBE_VIDEO_NOT_FOUND = 24 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/media_upload_error.py b/google/ads/googleads/v12/errors/types/media_upload_error.py new file mode 100644 index 000000000..240245b97 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/media_upload_error.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MediaUploadErrorEnum",}, +) + + +class MediaUploadErrorEnum(proto.Message): + r"""Container for enum describing possible media uploading + errors. + + """ + + class MediaUploadError(proto.Enum): + r"""Enum describing possible media uploading errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + FILE_TOO_BIG = 2 + UNPARSEABLE_IMAGE = 3 + ANIMATED_IMAGE_NOT_ALLOWED = 4 + FORMAT_NOT_ALLOWED = 5 + EXTERNAL_URL_NOT_ALLOWED = 6 + INVALID_URL_REFERENCE = 7 + MISSING_PRIMARY_MEDIA_BUNDLE_ENTRY = 8 + ANIMATED_VISUAL_EFFECT = 9 + ANIMATION_TOO_LONG = 10 + ASPECT_RATIO_NOT_ALLOWED = 11 + AUDIO_NOT_ALLOWED_IN_MEDIA_BUNDLE = 12 + CMYK_JPEG_NOT_ALLOWED = 13 + FLASH_NOT_ALLOWED = 14 + FRAME_RATE_TOO_HIGH = 15 + GOOGLE_WEB_DESIGNER_ZIP_FILE_NOT_PUBLISHED = 16 + IMAGE_CONSTRAINTS_VIOLATED = 17 + INVALID_MEDIA_BUNDLE = 18 + INVALID_MEDIA_BUNDLE_ENTRY = 19 + INVALID_MIME_TYPE = 20 + INVALID_PATH = 21 + LAYOUT_PROBLEM = 22 + MALFORMED_URL = 23 + MEDIA_BUNDLE_NOT_ALLOWED = 24 + MEDIA_BUNDLE_NOT_COMPATIBLE_TO_PRODUCT_TYPE = 25 + MEDIA_BUNDLE_REJECTED_BY_MULTIPLE_ASSET_SPECS = 26 + TOO_MANY_FILES_IN_MEDIA_BUNDLE = 27 + UNSUPPORTED_GOOGLE_WEB_DESIGNER_ENVIRONMENT = 28 + UNSUPPORTED_HTML5_FEATURE = 29 + URL_IN_MEDIA_BUNDLE_NOT_SSL_COMPLIANT = 30 + VIDEO_FILE_NAME_TOO_LONG = 31 + VIDEO_MULTIPLE_FILES_WITH_SAME_NAME = 32 + VIDEO_NOT_ALLOWED_IN_MEDIA_BUNDLE = 33 + CANNOT_UPLOAD_MEDIA_TYPE_THROUGH_API = 34 + DIMENSIONS_NOT_ALLOWED = 35 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/merchant_center_error.py b/google/ads/googleads/v12/errors/types/merchant_center_error.py new file mode 100644 index 000000000..182cc6df4 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/merchant_center_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MerchantCenterErrorEnum",}, +) + + +class MerchantCenterErrorEnum(proto.Message): + r"""Container for enum describing possible merchant center + errors. + + """ + + class MerchantCenterError(proto.Enum): + r"""Enum describing Merchant Center errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MERCHANT_ID_CANNOT_BE_ACCESSED = 2 + CUSTOMER_NOT_ALLOWED_FOR_SHOPPING_PERFORMANCE_MAX = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/multiplier_error.py b/google/ads/googleads/v12/errors/types/multiplier_error.py new file mode 100644 index 000000000..a75bf9785 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/multiplier_error.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MultiplierErrorEnum",}, +) + + +class MultiplierErrorEnum(proto.Message): + r"""Container for enum describing possible multiplier errors. + """ + + class MultiplierError(proto.Enum): + r"""Enum describing possible multiplier errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + MULTIPLIER_TOO_HIGH = 2 + MULTIPLIER_TOO_LOW = 3 + TOO_MANY_FRACTIONAL_DIGITS = 4 + MULTIPLIER_NOT_ALLOWED_FOR_BIDDING_STRATEGY = 5 + MULTIPLIER_NOT_ALLOWED_WHEN_BASE_BID_IS_MISSING = 6 + NO_MULTIPLIER_SPECIFIED = 7 + MULTIPLIER_CAUSES_BID_TO_EXCEED_DAILY_BUDGET = 8 + MULTIPLIER_CAUSES_BID_TO_EXCEED_MONTHLY_BUDGET = 9 + MULTIPLIER_CAUSES_BID_TO_EXCEED_CUSTOM_BUDGET = 10 + MULTIPLIER_CAUSES_BID_TO_EXCEED_MAX_ALLOWED_BID = 11 + BID_LESS_THAN_MIN_ALLOWED_BID_WITH_MULTIPLIER = 12 + MULTIPLIER_AND_BIDDING_STRATEGY_TYPE_MISMATCH = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/mutate_error.py b/google/ads/googleads/v12/errors/types/mutate_error.py new file mode 100644 index 000000000..35c6a2da6 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/mutate_error.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"MutateErrorEnum",}, +) + + +class MutateErrorEnum(proto.Message): + r"""Container for enum describing possible mutate errors. + """ + + class MutateError(proto.Enum): + r"""Enum describing possible mutate errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + RESOURCE_NOT_FOUND = 3 + ID_EXISTS_IN_MULTIPLE_MUTATES = 7 + INCONSISTENT_FIELD_VALUES = 8 + MUTATE_NOT_ALLOWED = 9 + RESOURCE_NOT_IN_GOOGLE_ADS = 10 + RESOURCE_ALREADY_EXISTS = 11 + RESOURCE_DOES_NOT_SUPPORT_VALIDATE_ONLY = 12 + OPERATION_DOES_NOT_SUPPORT_PARTIAL_FAILURE = 16 + RESOURCE_READ_ONLY = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/new_resource_creation_error.py b/google/ads/googleads/v12/errors/types/new_resource_creation_error.py new file mode 100644 index 000000000..4d1ec85b9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/new_resource_creation_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"NewResourceCreationErrorEnum",}, +) + + +class NewResourceCreationErrorEnum(proto.Message): + r"""Container for enum describing possible new resource creation + errors. + + """ + + class NewResourceCreationError(proto.Enum): + r"""Enum describing possible new resource creation errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CANNOT_SET_ID_FOR_CREATE = 2 + DUPLICATE_TEMP_IDS = 3 + TEMP_ID_RESOURCE_HAD_ERRORS = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/not_allowlisted_error.py b/google/ads/googleads/v12/errors/types/not_allowlisted_error.py new file mode 100644 index 000000000..55c303558 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/not_allowlisted_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"NotAllowlistedErrorEnum",}, +) + + +class NotAllowlistedErrorEnum(proto.Message): + r"""Container for enum describing possible not allowlisted + errors. + + """ + + class NotAllowlistedError(proto.Enum): + r"""Enum describing possible not allowlisted errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER_NOT_ALLOWLISTED_FOR_THIS_FEATURE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/not_empty_error.py b/google/ads/googleads/v12/errors/types/not_empty_error.py new file mode 100644 index 000000000..d7da1cd60 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/not_empty_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"NotEmptyErrorEnum",}, +) + + +class NotEmptyErrorEnum(proto.Message): + r"""Container for enum describing possible not empty errors. + """ + + class NotEmptyError(proto.Enum): + r"""Enum describing possible not empty errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EMPTY_LIST = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/null_error.py b/google/ads/googleads/v12/errors/types/null_error.py new file mode 100644 index 000000000..5cb1ebbad --- /dev/null +++ b/google/ads/googleads/v12/errors/types/null_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"NullErrorEnum",}, +) + + +class NullErrorEnum(proto.Message): + r"""Container for enum describing possible null errors. + """ + + class NullError(proto.Enum): + r"""Enum describing possible null errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NULL_CONTENT = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/offline_user_data_job_error.py b/google/ads/googleads/v12/errors/types/offline_user_data_job_error.py new file mode 100644 index 000000000..c490a1895 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/offline_user_data_job_error.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJobErrorEnum",}, +) + + +class OfflineUserDataJobErrorEnum(proto.Message): + r"""Container for enum describing possible offline user data job + errors. + + """ + + class OfflineUserDataJobError(proto.Enum): + r"""Enum describing possible request errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_USER_LIST_ID = 3 + INVALID_USER_LIST_TYPE = 4 + NOT_ON_ALLOWLIST_FOR_USER_ID = 33 + INCOMPATIBLE_UPLOAD_KEY_TYPE = 6 + MISSING_USER_IDENTIFIER = 7 + INVALID_MOBILE_ID_FORMAT = 8 + TOO_MANY_USER_IDENTIFIERS = 9 + NOT_ON_ALLOWLIST_FOR_STORE_SALES_DIRECT = 31 + NOT_ON_ALLOWLIST_FOR_UNIFIED_STORE_SALES = 32 + INVALID_PARTNER_ID = 11 + INVALID_ENCODING = 12 + INVALID_COUNTRY_CODE = 13 + INCOMPATIBLE_USER_IDENTIFIER = 14 + FUTURE_TRANSACTION_TIME = 15 + INVALID_CONVERSION_ACTION = 16 + MOBILE_ID_NOT_SUPPORTED = 17 + INVALID_OPERATION_ORDER = 18 + CONFLICTING_OPERATION = 19 + EXTERNAL_UPDATE_ID_ALREADY_EXISTS = 21 + JOB_ALREADY_STARTED = 22 + REMOVE_NOT_SUPPORTED = 23 + REMOVE_ALL_NOT_SUPPORTED = 24 + INVALID_SHA256_FORMAT = 25 + CUSTOM_KEY_DISABLED = 26 + CUSTOM_KEY_NOT_PREDEFINED = 27 + CUSTOM_KEY_NOT_SET = 29 + CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS = 30 + ATTRIBUTES_NOT_APPLICABLE_FOR_CUSTOMER_MATCH_USER_LIST = 34 + LIFETIME_VALUE_BUCKET_NOT_IN_RANGE = 35 + INCOMPATIBLE_USER_IDENTIFIER_FOR_ATTRIBUTES = 36 + FUTURE_TIME_NOT_ALLOWED = 37 + LAST_PURCHASE_TIME_LESS_THAN_ACQUISITION_TIME = 38 + CUSTOMER_IDENTIFIER_NOT_ALLOWED = 39 + INVALID_ITEM_ID = 40 + FIRST_PURCHASE_TIME_GREATER_THAN_LAST_PURCHASE_TIME = 42 + INVALID_LIFECYCLE_STAGE = 43 + INVALID_EVENT_VALUE = 44 + EVENT_ATTRIBUTE_ALL_FIELDS_ARE_REQUIRED = 45 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/operation_access_denied_error.py b/google/ads/googleads/v12/errors/types/operation_access_denied_error.py new file mode 100644 index 000000000..e08dde4e7 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/operation_access_denied_error.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"OperationAccessDeniedErrorEnum",}, +) + + +class OperationAccessDeniedErrorEnum(proto.Message): + r"""Container for enum describing possible operation access + denied errors. + + """ + + class OperationAccessDeniedError(proto.Enum): + r"""Enum describing possible operation access denied errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ACTION_NOT_PERMITTED = 2 + CREATE_OPERATION_NOT_PERMITTED = 3 + REMOVE_OPERATION_NOT_PERMITTED = 4 + UPDATE_OPERATION_NOT_PERMITTED = 5 + MUTATE_ACTION_NOT_PERMITTED_FOR_CLIENT = 6 + OPERATION_NOT_PERMITTED_FOR_CAMPAIGN_TYPE = 7 + CREATE_AS_REMOVED_NOT_PERMITTED = 8 + OPERATION_NOT_PERMITTED_FOR_REMOVED_RESOURCE = 9 + OPERATION_NOT_PERMITTED_FOR_AD_GROUP_TYPE = 10 + MUTATE_NOT_PERMITTED_FOR_CUSTOMER = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/operator_error.py b/google/ads/googleads/v12/errors/types/operator_error.py new file mode 100644 index 000000000..fbb45b0f0 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/operator_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"OperatorErrorEnum",}, +) + + +class OperatorErrorEnum(proto.Message): + r"""Container for enum describing possible operator errors. + """ + + class OperatorError(proto.Enum): + r"""Enum describing possible operator errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPERATOR_NOT_SUPPORTED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/partial_failure_error.py b/google/ads/googleads/v12/errors/types/partial_failure_error.py new file mode 100644 index 000000000..551875b3f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/partial_failure_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"PartialFailureErrorEnum",}, +) + + +class PartialFailureErrorEnum(proto.Message): + r"""Container for enum describing possible partial failure + errors. + + """ + + class PartialFailureError(proto.Enum): + r"""Enum describing possible partial failure errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + PARTIAL_FAILURE_MODE_REQUIRED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/payments_account_error.py b/google/ads/googleads/v12/errors/types/payments_account_error.py new file mode 100644 index 000000000..c8dffe29b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/payments_account_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"PaymentsAccountErrorEnum",}, +) + + +class PaymentsAccountErrorEnum(proto.Message): + r"""Container for enum describing possible errors in payments + account service. + + """ + + class PaymentsAccountError(proto.Enum): + r"""Enum describing possible errors in payments account service.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_SUPPORTED_FOR_MANAGER_CUSTOMER = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/policy_finding_error.py b/google/ads/googleads/v12/errors/types/policy_finding_error.py new file mode 100644 index 000000000..c2bfbfdaf --- /dev/null +++ b/google/ads/googleads/v12/errors/types/policy_finding_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"PolicyFindingErrorEnum",}, +) + + +class PolicyFindingErrorEnum(proto.Message): + r"""Container for enum describing possible policy finding errors. + """ + + class PolicyFindingError(proto.Enum): + r"""Enum describing possible policy finding errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + POLICY_FINDING = 2 + POLICY_TOPIC_NOT_FOUND = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/policy_validation_parameter_error.py b/google/ads/googleads/v12/errors/types/policy_validation_parameter_error.py new file mode 100644 index 000000000..fc8386e14 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/policy_validation_parameter_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"PolicyValidationParameterErrorEnum",}, +) + + +class PolicyValidationParameterErrorEnum(proto.Message): + r"""Container for enum describing possible policy validation + parameter errors. + + """ + + class PolicyValidationParameterError(proto.Enum): + r"""Enum describing possible policy validation parameter errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + UNSUPPORTED_AD_TYPE_FOR_IGNORABLE_POLICY_TOPICS = 2 + UNSUPPORTED_AD_TYPE_FOR_EXEMPT_POLICY_VIOLATION_KEYS = 3 + CANNOT_SET_BOTH_IGNORABLE_POLICY_TOPICS_AND_EXEMPT_POLICY_VIOLATION_KEYS = ( + 4 + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/policy_violation_error.py b/google/ads/googleads/v12/errors/types/policy_violation_error.py new file mode 100644 index 000000000..587a99747 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/policy_violation_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"PolicyViolationErrorEnum",}, +) + + +class PolicyViolationErrorEnum(proto.Message): + r"""Container for enum describing possible policy violation + errors. + + """ + + class PolicyViolationError(proto.Enum): + r"""Enum describing possible policy violation errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + POLICY_ERROR = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/query_error.py b/google/ads/googleads/v12/errors/types/query_error.py new file mode 100644 index 000000000..d3572765e --- /dev/null +++ b/google/ads/googleads/v12/errors/types/query_error.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"QueryErrorEnum",}, +) + + +class QueryErrorEnum(proto.Message): + r"""Container for enum describing possible query errors. + """ + + class QueryError(proto.Enum): + r"""Enum describing possible query errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + QUERY_ERROR = 50 + BAD_ENUM_CONSTANT = 18 + BAD_ESCAPE_SEQUENCE = 7 + BAD_FIELD_NAME = 12 + BAD_LIMIT_VALUE = 15 + BAD_NUMBER = 5 + BAD_OPERATOR = 3 + BAD_PARAMETER_NAME = 61 + BAD_PARAMETER_VALUE = 62 + BAD_RESOURCE_TYPE_IN_FROM_CLAUSE = 45 + BAD_SYMBOL = 2 + BAD_VALUE = 4 + DATE_RANGE_TOO_WIDE = 36 + DATE_RANGE_TOO_NARROW = 60 + EXPECTED_AND = 30 + EXPECTED_BY = 14 + EXPECTED_DIMENSION_FIELD_IN_SELECT_CLAUSE = 37 + EXPECTED_FILTERS_ON_DATE_RANGE = 55 + EXPECTED_FROM = 44 + EXPECTED_LIST = 41 + EXPECTED_REFERENCED_FIELD_IN_SELECT_CLAUSE = 16 + EXPECTED_SELECT = 13 + EXPECTED_SINGLE_VALUE = 42 + EXPECTED_VALUE_WITH_BETWEEN_OPERATOR = 29 + INVALID_DATE_FORMAT = 38 + MISALIGNED_DATE_FOR_FILTER = 64 + INVALID_STRING_VALUE = 57 + INVALID_VALUE_WITH_BETWEEN_OPERATOR = 26 + INVALID_VALUE_WITH_DURING_OPERATOR = 22 + INVALID_VALUE_WITH_LIKE_OPERATOR = 56 + OPERATOR_FIELD_MISMATCH = 35 + PROHIBITED_EMPTY_LIST_IN_CONDITION = 28 + PROHIBITED_ENUM_CONSTANT = 54 + PROHIBITED_FIELD_COMBINATION_IN_SELECT_CLAUSE = 31 + PROHIBITED_FIELD_IN_ORDER_BY_CLAUSE = 40 + PROHIBITED_FIELD_IN_SELECT_CLAUSE = 23 + PROHIBITED_FIELD_IN_WHERE_CLAUSE = 24 + PROHIBITED_RESOURCE_TYPE_IN_FROM_CLAUSE = 43 + PROHIBITED_RESOURCE_TYPE_IN_SELECT_CLAUSE = 48 + PROHIBITED_RESOURCE_TYPE_IN_WHERE_CLAUSE = 58 + PROHIBITED_METRIC_IN_SELECT_OR_WHERE_CLAUSE = 49 + PROHIBITED_SEGMENT_IN_SELECT_OR_WHERE_CLAUSE = 51 + PROHIBITED_SEGMENT_WITH_METRIC_IN_SELECT_OR_WHERE_CLAUSE = 53 + LIMIT_VALUE_TOO_LOW = 25 + PROHIBITED_NEWLINE_IN_STRING = 8 + PROHIBITED_VALUE_COMBINATION_IN_LIST = 10 + PROHIBITED_VALUE_COMBINATION_WITH_BETWEEN_OPERATOR = 21 + STRING_NOT_TERMINATED = 6 + TOO_MANY_SEGMENTS = 34 + UNEXPECTED_END_OF_QUERY = 9 + UNEXPECTED_FROM_CLAUSE = 47 + UNRECOGNIZED_FIELD = 32 + UNEXPECTED_INPUT = 11 + REQUESTED_METRICS_FOR_MANAGER = 59 + FILTER_HAS_TOO_MANY_VALUES = 63 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/quota_error.py b/google/ads/googleads/v12/errors/types/quota_error.py new file mode 100644 index 000000000..1b72b7f7a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/quota_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"QuotaErrorEnum",}, +) + + +class QuotaErrorEnum(proto.Message): + r"""Container for enum describing possible quota errors. + """ + + class QuotaError(proto.Enum): + r"""Enum describing possible quota errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + RESOURCE_EXHAUSTED = 2 + ACCESS_PROHIBITED = 3 + RESOURCE_TEMPORARILY_EXHAUSTED = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/range_error.py b/google/ads/googleads/v12/errors/types/range_error.py new file mode 100644 index 000000000..bd4fdea77 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/range_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"RangeErrorEnum",}, +) + + +class RangeErrorEnum(proto.Message): + r"""Container for enum describing possible range errors. + """ + + class RangeError(proto.Enum): + r"""Enum describing possible range errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + TOO_LOW = 2 + TOO_HIGH = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/reach_plan_error.py b/google/ads/googleads/v12/errors/types/reach_plan_error.py new file mode 100644 index 000000000..8da384e37 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/reach_plan_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ReachPlanErrorEnum",}, +) + + +class ReachPlanErrorEnum(proto.Message): + r"""Container for enum describing possible errors returned from + the ReachPlanService. + + """ + + class ReachPlanError(proto.Enum): + r"""Enum describing possible errors from ReachPlanService.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_FORECASTABLE_MISSING_RATE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/recommendation_error.py b/google/ads/googleads/v12/errors/types/recommendation_error.py new file mode 100644 index 000000000..bead38781 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/recommendation_error.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"RecommendationErrorEnum",}, +) + + +class RecommendationErrorEnum(proto.Message): + r"""Container for enum describing possible errors from applying a + recommendation. + + """ + + class RecommendationError(proto.Enum): + r"""Enum describing possible errors from applying a + recommendation. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + BUDGET_AMOUNT_TOO_SMALL = 2 + BUDGET_AMOUNT_TOO_LARGE = 3 + INVALID_BUDGET_AMOUNT = 4 + POLICY_ERROR = 5 + INVALID_BID_AMOUNT = 6 + ADGROUP_KEYWORD_LIMIT = 7 + RECOMMENDATION_ALREADY_APPLIED = 8 + RECOMMENDATION_INVALIDATED = 9 + TOO_MANY_OPERATIONS = 10 + NO_OPERATIONS = 11 + DIFFERENT_TYPES_NOT_SUPPORTED = 12 + DUPLICATE_RESOURCE_NAME = 13 + RECOMMENDATION_ALREADY_DISMISSED = 14 + INVALID_APPLY_REQUEST = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/region_code_error.py b/google/ads/googleads/v12/errors/types/region_code_error.py new file mode 100644 index 000000000..8cfdfb96f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/region_code_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"RegionCodeErrorEnum",}, +) + + +class RegionCodeErrorEnum(proto.Message): + r"""Container for enum describing possible region code errors. + """ + + class RegionCodeError(proto.Enum): + r"""Enum describing possible region code errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_REGION_CODE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/request_error.py b/google/ads/googleads/v12/errors/types/request_error.py new file mode 100644 index 000000000..5791c3579 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/request_error.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"RequestErrorEnum",}, +) + + +class RequestErrorEnum(proto.Message): + r"""Container for enum describing possible request errors. + """ + + class RequestError(proto.Enum): + r"""Enum describing possible request errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + RESOURCE_NAME_MISSING = 3 + RESOURCE_NAME_MALFORMED = 4 + BAD_RESOURCE_ID = 17 + INVALID_CUSTOMER_ID = 16 + OPERATION_REQUIRED = 5 + RESOURCE_NOT_FOUND = 6 + INVALID_PAGE_TOKEN = 7 + EXPIRED_PAGE_TOKEN = 8 + INVALID_PAGE_SIZE = 22 + REQUIRED_FIELD_MISSING = 9 + IMMUTABLE_FIELD = 11 + TOO_MANY_MUTATE_OPERATIONS = 13 + CANNOT_BE_EXECUTED_BY_MANAGER_ACCOUNT = 14 + CANNOT_MODIFY_FOREIGN_FIELD = 15 + INVALID_ENUM_VALUE = 18 + DEVELOPER_TOKEN_PARAMETER_MISSING = 19 + LOGIN_CUSTOMER_ID_PARAMETER_MISSING = 20 + VALIDATE_ONLY_REQUEST_HAS_PAGE_TOKEN = 21 + CANNOT_RETURN_SUMMARY_ROW_FOR_REQUEST_WITHOUT_METRICS = 29 + CANNOT_RETURN_SUMMARY_ROW_FOR_VALIDATE_ONLY_REQUESTS = 30 + INCONSISTENT_RETURN_SUMMARY_ROW_VALUE = 31 + TOTAL_RESULTS_COUNT_NOT_ORIGINALLY_REQUESTED = 32 + RPC_DEADLINE_TOO_SHORT = 33 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/resource_access_denied_error.py b/google/ads/googleads/v12/errors/types/resource_access_denied_error.py new file mode 100644 index 000000000..c143eb59b --- /dev/null +++ b/google/ads/googleads/v12/errors/types/resource_access_denied_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ResourceAccessDeniedErrorEnum",}, +) + + +class ResourceAccessDeniedErrorEnum(proto.Message): + r"""Container for enum describing possible resource access denied + errors. + + """ + + class ResourceAccessDeniedError(proto.Enum): + r"""Enum describing possible resource access denied errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + WRITE_ACCESS_DENIED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/resource_count_limit_exceeded_error.py b/google/ads/googleads/v12/errors/types/resource_count_limit_exceeded_error.py new file mode 100644 index 000000000..f6f6912aa --- /dev/null +++ b/google/ads/googleads/v12/errors/types/resource_count_limit_exceeded_error.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ResourceCountLimitExceededErrorEnum",}, +) + + +class ResourceCountLimitExceededErrorEnum(proto.Message): + r"""Container for enum describing possible resource count limit + exceeded errors. + + """ + + class ResourceCountLimitExceededError(proto.Enum): + r"""Enum describing possible resource count limit exceeded + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + ACCOUNT_LIMIT = 2 + CAMPAIGN_LIMIT = 3 + ADGROUP_LIMIT = 4 + AD_GROUP_AD_LIMIT = 5 + AD_GROUP_CRITERION_LIMIT = 6 + SHARED_SET_LIMIT = 7 + MATCHING_FUNCTION_LIMIT = 8 + RESPONSE_ROW_LIMIT_EXCEEDED = 9 + RESOURCE_LIMIT = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/setting_error.py b/google/ads/googleads/v12/errors/types/setting_error.py new file mode 100644 index 000000000..8c03ca1c4 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/setting_error.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"SettingErrorEnum",}, +) + + +class SettingErrorEnum(proto.Message): + r"""Container for enum describing possible setting errors. + """ + + class SettingError(proto.Enum): + r"""Enum describing possible setting errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + SETTING_TYPE_IS_NOT_AVAILABLE = 3 + SETTING_TYPE_IS_NOT_COMPATIBLE_WITH_CAMPAIGN = 4 + TARGETING_SETTING_CONTAINS_INVALID_CRITERION_TYPE_GROUP = 5 + TARGETING_SETTING_DEMOGRAPHIC_CRITERION_TYPE_GROUPS_MUST_BE_SET_TO_TARGET_ALL = ( + 6 + ) + TARGETING_SETTING_CANNOT_CHANGE_TARGET_ALL_TO_FALSE_FOR_DEMOGRAPHIC_CRITERION_TYPE_GROUP = ( + 7 + ) + DYNAMIC_SEARCH_ADS_SETTING_AT_LEAST_ONE_FEED_ID_MUST_BE_PRESENT = 8 + DYNAMIC_SEARCH_ADS_SETTING_CONTAINS_INVALID_DOMAIN_NAME = 9 + DYNAMIC_SEARCH_ADS_SETTING_CONTAINS_SUBDOMAIN_NAME = 10 + DYNAMIC_SEARCH_ADS_SETTING_CONTAINS_INVALID_LANGUAGE_CODE = 11 + TARGET_ALL_IS_NOT_ALLOWED_FOR_PLACEMENT_IN_SEARCH_CAMPAIGN = 12 + SETTING_VALUE_NOT_COMPATIBLE_WITH_CAMPAIGN = 20 + BID_ONLY_IS_NOT_ALLOWED_TO_BE_MODIFIED_WITH_CUSTOMER_MATCH_TARGETING = ( + 21 + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/shared_criterion_error.py b/google/ads/googleads/v12/errors/types/shared_criterion_error.py new file mode 100644 index 000000000..f2eb61e98 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/shared_criterion_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"SharedCriterionErrorEnum",}, +) + + +class SharedCriterionErrorEnum(proto.Message): + r"""Container for enum describing possible shared criterion + errors. + + """ + + class SharedCriterionError(proto.Enum): + r"""Enum describing possible shared criterion errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CRITERION_TYPE_NOT_ALLOWED_FOR_SHARED_SET_TYPE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/shared_set_error.py b/google/ads/googleads/v12/errors/types/shared_set_error.py new file mode 100644 index 000000000..2c5bdb136 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/shared_set_error.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"SharedSetErrorEnum",}, +) + + +class SharedSetErrorEnum(proto.Message): + r"""Container for enum describing possible shared set errors. + """ + + class SharedSetError(proto.Enum): + r"""Enum describing possible shared set errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER_CANNOT_CREATE_SHARED_SET_OF_THIS_TYPE = 2 + DUPLICATE_NAME = 3 + SHARED_SET_REMOVED = 4 + SHARED_SET_IN_USE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/size_limit_error.py b/google/ads/googleads/v12/errors/types/size_limit_error.py new file mode 100644 index 000000000..79398b579 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/size_limit_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"SizeLimitErrorEnum",}, +) + + +class SizeLimitErrorEnum(proto.Message): + r"""Container for enum describing possible size limit errors. + """ + + class SizeLimitError(proto.Enum): + r"""Enum describing possible size limit errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + REQUEST_SIZE_LIMIT_EXCEEDED = 2 + RESPONSE_SIZE_LIMIT_EXCEEDED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/smart_campaign_error.py b/google/ads/googleads/v12/errors/types/smart_campaign_error.py new file mode 100644 index 000000000..72169a420 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/smart_campaign_error.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"SmartCampaignErrorEnum",}, +) + + +class SmartCampaignErrorEnum(proto.Message): + r"""Container for enum describing possible Smart campaign errors. + """ + + class SmartCampaignError(proto.Enum): + r"""Enum describing possible Smart campaign errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_BUSINESS_LOCATION_ID = 2 + INVALID_CAMPAIGN = 3 + BUSINESS_NAME_OR_BUSINESS_LOCATION_ID_MISSING = 4 + REQUIRED_SUGGESTION_FIELD_MISSING = 5 + GEO_TARGETS_REQUIRED = 6 + CANNOT_DETERMINE_SUGGESTION_LOCALE = 7 + FINAL_URL_NOT_CRAWLABLE = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/string_format_error.py b/google/ads/googleads/v12/errors/types/string_format_error.py new file mode 100644 index 000000000..8b7cd68a9 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/string_format_error.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"StringFormatErrorEnum",}, +) + + +class StringFormatErrorEnum(proto.Message): + r"""Container for enum describing possible string format errors. + """ + + class StringFormatError(proto.Enum): + r"""Enum describing possible string format errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ILLEGAL_CHARS = 2 + INVALID_FORMAT = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/string_length_error.py b/google/ads/googleads/v12/errors/types/string_length_error.py new file mode 100644 index 000000000..4933c434c --- /dev/null +++ b/google/ads/googleads/v12/errors/types/string_length_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"StringLengthErrorEnum",}, +) + + +class StringLengthErrorEnum(proto.Message): + r"""Container for enum describing possible string length errors. + """ + + class StringLengthError(proto.Enum): + r"""Enum describing possible string length errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EMPTY = 4 + TOO_SHORT = 2 + TOO_LONG = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/third_party_app_analytics_link_error.py b/google/ads/googleads/v12/errors/types/third_party_app_analytics_link_error.py new file mode 100644 index 000000000..70ecd51be --- /dev/null +++ b/google/ads/googleads/v12/errors/types/third_party_app_analytics_link_error.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"ThirdPartyAppAnalyticsLinkErrorEnum",}, +) + + +class ThirdPartyAppAnalyticsLinkErrorEnum(proto.Message): + r"""Container for enum describing possible third party app + analytics link errors. + + """ + + class ThirdPartyAppAnalyticsLinkError(proto.Enum): + r"""Enum describing possible third party app analytics link + errors. + """ + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_ANALYTICS_PROVIDER_ID = 2 + INVALID_MOBILE_APP_ID = 3 + MOBILE_APP_IS_NOT_ENABLED = 4 + CANNOT_REGENERATE_SHAREABLE_LINK_ID_FOR_REMOVED_LINK = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/time_zone_error.py b/google/ads/googleads/v12/errors/types/time_zone_error.py new file mode 100644 index 000000000..df7c40ef2 --- /dev/null +++ b/google/ads/googleads/v12/errors/types/time_zone_error.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"TimeZoneErrorEnum",}, +) + + +class TimeZoneErrorEnum(proto.Message): + r"""Container for enum describing possible time zone errors. + """ + + class TimeZoneError(proto.Enum): + r"""Enum describing possible currency code errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_TIME_ZONE = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/url_field_error.py b/google/ads/googleads/v12/errors/types/url_field_error.py new file mode 100644 index 000000000..e4818c56d --- /dev/null +++ b/google/ads/googleads/v12/errors/types/url_field_error.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"UrlFieldErrorEnum",}, +) + + +class UrlFieldErrorEnum(proto.Message): + r"""Container for enum describing possible url field errors. + """ + + class UrlFieldError(proto.Enum): + r"""Enum describing possible url field errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_TRACKING_URL_TEMPLATE = 2 + INVALID_TAG_IN_TRACKING_URL_TEMPLATE = 3 + MISSING_TRACKING_URL_TEMPLATE_TAG = 4 + MISSING_PROTOCOL_IN_TRACKING_URL_TEMPLATE = 5 + INVALID_PROTOCOL_IN_TRACKING_URL_TEMPLATE = 6 + MALFORMED_TRACKING_URL_TEMPLATE = 7 + MISSING_HOST_IN_TRACKING_URL_TEMPLATE = 8 + INVALID_TLD_IN_TRACKING_URL_TEMPLATE = 9 + REDUNDANT_NESTED_TRACKING_URL_TEMPLATE_TAG = 10 + INVALID_FINAL_URL = 11 + INVALID_TAG_IN_FINAL_URL = 12 + REDUNDANT_NESTED_FINAL_URL_TAG = 13 + MISSING_PROTOCOL_IN_FINAL_URL = 14 + INVALID_PROTOCOL_IN_FINAL_URL = 15 + MALFORMED_FINAL_URL = 16 + MISSING_HOST_IN_FINAL_URL = 17 + INVALID_TLD_IN_FINAL_URL = 18 + INVALID_FINAL_MOBILE_URL = 19 + INVALID_TAG_IN_FINAL_MOBILE_URL = 20 + REDUNDANT_NESTED_FINAL_MOBILE_URL_TAG = 21 + MISSING_PROTOCOL_IN_FINAL_MOBILE_URL = 22 + INVALID_PROTOCOL_IN_FINAL_MOBILE_URL = 23 + MALFORMED_FINAL_MOBILE_URL = 24 + MISSING_HOST_IN_FINAL_MOBILE_URL = 25 + INVALID_TLD_IN_FINAL_MOBILE_URL = 26 + INVALID_FINAL_APP_URL = 27 + INVALID_TAG_IN_FINAL_APP_URL = 28 + REDUNDANT_NESTED_FINAL_APP_URL_TAG = 29 + MULTIPLE_APP_URLS_FOR_OSTYPE = 30 + INVALID_OSTYPE = 31 + INVALID_PROTOCOL_FOR_APP_URL = 32 + INVALID_PACKAGE_ID_FOR_APP_URL = 33 + URL_CUSTOM_PARAMETERS_COUNT_EXCEEDS_LIMIT = 34 + INVALID_CHARACTERS_IN_URL_CUSTOM_PARAMETER_KEY = 39 + INVALID_CHARACTERS_IN_URL_CUSTOM_PARAMETER_VALUE = 40 + INVALID_TAG_IN_URL_CUSTOM_PARAMETER_VALUE = 41 + REDUNDANT_NESTED_URL_CUSTOM_PARAMETER_TAG = 42 + MISSING_PROTOCOL = 43 + INVALID_PROTOCOL = 52 + INVALID_URL = 44 + DESTINATION_URL_DEPRECATED = 45 + INVALID_TAG_IN_URL = 46 + MISSING_URL_TAG = 47 + DUPLICATE_URL_ID = 48 + INVALID_URL_ID = 49 + FINAL_URL_SUFFIX_MALFORMED = 50 + INVALID_TAG_IN_FINAL_URL_SUFFIX = 51 + INVALID_TOP_LEVEL_DOMAIN = 53 + MALFORMED_TOP_LEVEL_DOMAIN = 54 + MALFORMED_URL = 55 + MISSING_HOST = 56 + NULL_CUSTOM_PARAMETER_VALUE = 57 + VALUE_TRACK_PARAMETER_NOT_SUPPORTED = 58 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/user_data_error.py b/google/ads/googleads/v12/errors/types/user_data_error.py new file mode 100644 index 000000000..cfe73775a --- /dev/null +++ b/google/ads/googleads/v12/errors/types/user_data_error.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"UserDataErrorEnum",}, +) + + +class UserDataErrorEnum(proto.Message): + r"""Container for enum describing possible user data errors. + """ + + class UserDataError(proto.Enum): + r"""Enum describing possible request errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + OPERATIONS_FOR_CUSTOMER_MATCH_NOT_ALLOWED = 2 + TOO_MANY_USER_IDENTIFIERS = 3 + USER_LIST_NOT_APPLICABLE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/user_list_error.py b/google/ads/googleads/v12/errors/types/user_list_error.py new file mode 100644 index 000000000..ae300eb4f --- /dev/null +++ b/google/ads/googleads/v12/errors/types/user_list_error.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"UserListErrorEnum",}, +) + + +class UserListErrorEnum(proto.Message): + r"""Container for enum describing possible user list errors. + """ + + class UserListError(proto.Enum): + r"""Enum describing possible user list errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + EXTERNAL_REMARKETING_USER_LIST_MUTATE_NOT_SUPPORTED = 2 + CONCRETE_TYPE_REQUIRED = 3 + CONVERSION_TYPE_ID_REQUIRED = 4 + DUPLICATE_CONVERSION_TYPES = 5 + INVALID_CONVERSION_TYPE = 6 + INVALID_DESCRIPTION = 7 + INVALID_NAME = 8 + INVALID_TYPE = 9 + CAN_NOT_ADD_LOGICAL_LIST_AS_LOGICAL_LIST_OPERAND = 10 + INVALID_USER_LIST_LOGICAL_RULE_OPERAND = 11 + NAME_ALREADY_USED = 12 + NEW_CONVERSION_TYPE_NAME_REQUIRED = 13 + CONVERSION_TYPE_NAME_ALREADY_USED = 14 + OWNERSHIP_REQUIRED_FOR_SET = 15 + USER_LIST_MUTATE_NOT_SUPPORTED = 16 + INVALID_RULE = 17 + INVALID_DATE_RANGE = 27 + CAN_NOT_MUTATE_SENSITIVE_USERLIST = 28 + MAX_NUM_RULEBASED_USERLISTS = 29 + CANNOT_MODIFY_BILLABLE_RECORD_COUNT = 30 + APP_ID_NOT_SET = 31 + USERLIST_NAME_IS_RESERVED_FOR_SYSTEM_LIST = 32 + ADVERTISER_NOT_ON_ALLOWLIST_FOR_USING_UPLOADED_DATA = 37 + RULE_TYPE_IS_NOT_SUPPORTED = 34 + CAN_NOT_ADD_A_SIMILAR_USERLIST_AS_LOGICAL_LIST_OPERAND = 35 + CAN_NOT_MIX_CRM_BASED_IN_LOGICAL_LIST_WITH_OTHER_LISTS = 36 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/errors/types/youtube_video_registration_error.py b/google/ads/googleads/v12/errors/types/youtube_video_registration_error.py new file mode 100644 index 000000000..5230d94bb --- /dev/null +++ b/google/ads/googleads/v12/errors/types/youtube_video_registration_error.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.errors", + marshal="google.ads.googleads.v12", + manifest={"YoutubeVideoRegistrationErrorEnum",}, +) + + +class YoutubeVideoRegistrationErrorEnum(proto.Message): + r"""Container for enum describing YouTube video registration + errors. + + """ + + class YoutubeVideoRegistrationError(proto.Enum): + r"""Enum describing YouTube video registration errors.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + VIDEO_NOT_FOUND = 2 + VIDEO_NOT_ACCESSIBLE = 3 + VIDEO_NOT_ELIGIBLE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/__init__.py b/google/ads/googleads/v12/resources/__init__.py new file mode 100644 index 000000000..c620a6d05 --- /dev/null +++ b/google/ads/googleads/v12/resources/__init__.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +__all__ = ( + "AccessibleBiddingStrategy", + "AccountBudget", + "AccountBudgetProposal", + "AccountLink", + "Ad", + "AdGroup", + "AdGroupAd", + "AdGroupAdAssetCombinationView", + "AdGroupAdAssetPolicySummary", + "AdGroupAdAssetView", + "AdGroupAdLabel", + "AdGroupAdPolicySummary", + "AdGroupAsset", + "AdGroupAssetSet", + "AdGroupAudienceView", + "AdGroupBidModifier", + "AdGroupCriterion", + "AdGroupCriterionCustomizer", + "AdGroupCriterionLabel", + "AdGroupCriterionSimulation", + "AdGroupCustomizer", + "AdGroupExtensionSetting", + "AdGroupFeed", + "AdGroupLabel", + "AdGroupSimulation", + "AdParameter", + "AdScheduleView", + "AdvertisingPartnerLinkIdentifier", + "AgeRangeView", + "Asset", + "AssetFieldTypeView", + "AssetGroup", + "AssetGroupAsset", + "AssetGroupListingGroupFilter", + "AssetGroupProductGroupView", + "AssetGroupSignal", + "AssetPolicySummary", + "AssetSet", + "AssetSetAsset", + "AssetSetTypeView", + "AttributeFieldMapping", + "Audience", + "BatchJob", + "BiddingDataExclusion", + "BiddingSeasonalityAdjustment", + "BiddingStrategy", + "BiddingStrategySimulation", + "BillingSetup", + "CallReportingSetting", + "CallView", + "Campaign", + "CampaignAsset", + "CampaignAssetSet", + "CampaignAudienceView", + "CampaignBidModifier", + "CampaignBudget", + "CampaignConversionGoal", + "CampaignCriterion", + "CampaignCriterionSimulation", + "CampaignCustomizer", + "CampaignDraft", + "CampaignExtensionSetting", + "CampaignFeed", + "CampaignGroup", + "CampaignLabel", + "CampaignSharedSet", + "CampaignSimulation", + "CarrierConstant", + "ChangeEvent", + "ChangeStatus", + "ClickView", + "CombinedAudience", + "ConversionAction", + "ConversionCustomVariable", + "ConversionGoalCampaignConfig", + "ConversionTrackingSetting", + "ConversionValueRule", + "ConversionValueRuleSet", + "CurrencyConstant", + "CustomAudience", + "CustomAudienceMember", + "CustomConversionGoal", + "CustomInterest", + "CustomInterestMember", + "CustomLeadFormSubmissionField", + "Customer", + "CustomerAsset", + "CustomerAssetSet", + "CustomerClient", + "CustomerClientLink", + "CustomerConversionGoal", + "CustomerCustomizer", + "CustomerExtensionSetting", + "CustomerFeed", + "CustomerLabel", + "CustomerManagerLink", + "CustomerNegativeCriterion", + "CustomerUserAccess", + "CustomerUserAccessInvitation", + "CustomizerAttribute", + "DataPartnerLinkIdentifier", + "DetailPlacementView", + "DetailedDemographic", + "DisplayKeywordView", + "DistanceView", + "DomainCategory", + "DynamicSearchAdsSearchTermView", + "ExpandedLandingPageView", + "Experiment", + "ExperimentArm", + "ExtensionFeedItem", + "Feed", + "FeedAttribute", + "FeedAttributeOperation", + "FeedItem", + "FeedItemAttributeValue", + "FeedItemPlaceholderPolicyInfo", + "FeedItemSet", + "FeedItemSetLink", + "FeedItemTarget", + "FeedItemValidationError", + "FeedMapping", + "FeedPlaceholderView", + "GenderView", + "GeoTargetConstant", + "GeographicView", + "GoogleAdsField", + "GoogleAdsLinkIdentifier", + "GroupPlacementView", + "HotelCenterLinkIdentifier", + "HotelGroupView", + "HotelPerformanceView", + "HotelReconciliation", + "IncomeRangeView", + "Invoice", + "KeywordPlan", + "KeywordPlanAdGroup", + "KeywordPlanAdGroupKeyword", + "KeywordPlanCampaign", + "KeywordPlanCampaignKeyword", + "KeywordPlanForecastPeriod", + "KeywordPlanGeoTarget", + "KeywordThemeConstant", + "KeywordView", + "Label", + "LandingPageView", + "LanguageConstant", + "LeadFormSubmissionData", + "LeadFormSubmissionField", + "LifeEvent", + "ListingGroupFilterDimension", + "LocationView", + "ManagedPlacementView", + "MediaAudio", + "MediaBundle", + "MediaFile", + "MediaImage", + "MediaVideo", + "MerchantCenterLink", + "MobileAppCategoryConstant", + "MobileDeviceConstant", + "OfflineUserDataJob", + "OfflineUserDataJobMetadata", + "OperatingSystemVersionConstant", + "PaidOrganicSearchTermView", + "ParentalStatusView", + "PaymentsAccount", + "PerStoreView", + "ProductBiddingCategoryConstant", + "ProductGroupView", + "Recommendation", + "RemarketingAction", + "RemarketingSetting", + "SearchTermView", + "SharedCriterion", + "SharedSet", + "ShoppingPerformanceView", + "SmartCampaignSearchTermView", + "SmartCampaignSetting", + "ThirdPartyAppAnalyticsLink", + "ThirdPartyAppAnalyticsLinkIdentifier", + "TopicConstant", + "TopicView", + "UserInterest", + "UserList", + "UserLocationView", + "Video", + "WebpageView", +) diff --git a/google/ads/googleads/v12/resources/services/__init__.py b/google/ads/googleads/v12/resources/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/resources/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/resources/types/__init__.py b/google/ads/googleads/v12/resources/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/resources/types/accessible_bidding_strategy.py b/google/ads/googleads/v12/resources/types/accessible_bidding_strategy.py new file mode 100644 index 000000000..769efed2f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/accessible_bidding_strategy.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import bidding_strategy_type +from google.ads.googleads.v12.enums.types import ( + target_impression_share_location, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AccessibleBiddingStrategy",}, +) + + +class AccessibleBiddingStrategy(proto.Message): + r"""Represents a view of BiddingStrategies owned by and shared + with the customer. + In contrast to BiddingStrategy, this resource includes + strategies owned by managers of the customer and shared with + this customer - in addition to strategies owned by this + customer. This resource does not provide metrics and only + exposes a limited subset of the BiddingStrategy attributes. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the accessible bidding + strategy. AccessibleBiddingStrategy resource names have the + form: + + ``customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}`` + id (int): + Output only. The ID of the bidding strategy. + name (str): + Output only. The name of the bidding + strategy. + type_ (google.ads.googleads.v12.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + Output only. The type of the bidding + strategy. + owner_customer_id (int): + Output only. The ID of the Customer which + owns the bidding strategy. + owner_descriptive_name (str): + Output only. descriptive_name of the Customer which owns the + bidding strategy. + maximize_conversion_value (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.MaximizeConversionValue): + Output only. An automated bidding strategy to + help get the most conversion value for your + campaigns while spending your budget. + + This field is a member of `oneof`_ ``scheme``. + maximize_conversions (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.MaximizeConversions): + Output only. An automated bidding strategy to + help get the most conversions for your campaigns + while spending your budget. + + This field is a member of `oneof`_ ``scheme``. + target_cpa (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.TargetCpa): + Output only. A bidding strategy that sets + bids to help get as many conversions as possible + at the target cost-per-acquisition (CPA) you + set. + + This field is a member of `oneof`_ ``scheme``. + target_impression_share (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.TargetImpressionShare): + Output only. A bidding strategy that + automatically optimizes towards a chosen + percentage of impressions. + + This field is a member of `oneof`_ ``scheme``. + target_roas (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.TargetRoas): + Output only. A bidding strategy that helps + you maximize revenue while averaging a specific + target Return On Ad Spend (ROAS). + + This field is a member of `oneof`_ ``scheme``. + target_spend (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy.TargetSpend): + Output only. A bid strategy that sets your + bids to help get as many clicks as possible + within your budget. + + This field is a member of `oneof`_ ``scheme``. + """ + + class MaximizeConversionValue(proto.Message): + r"""An automated bidding strategy to help get the most conversion + value for your campaigns while spending your budget. + + Attributes: + target_roas (float): + Output only. The target return on ad spend + (ROAS) option. If set, the bid strategy will + maximize revenue while averaging the target + return on ad spend. If the target ROAS is high, + the bid strategy may not be able to spend the + full budget. If the target ROAS is not set, the + bid strategy will aim to achieve the highest + possible ROAS for the budget. + """ + + target_roas = proto.Field(proto.DOUBLE, number=1,) + + class MaximizeConversions(proto.Message): + r"""An automated bidding strategy to help get the most + conversions for your campaigns while spending your budget. + + Attributes: + target_cpa_micros (int): + Output only. The target cost per acquisition + (CPA) option. This is the average amount that + you would like to spend per acquisition. + """ + + target_cpa_micros = proto.Field(proto.INT64, number=2,) + + class TargetCpa(proto.Message): + r"""An automated bid strategy that sets bids to help get as many + conversions as possible at the target cost-per-acquisition (CPA) + you set. + + Attributes: + target_cpa_micros (int): + Output only. Average CPA target. + This target should be greater than or equal to + minimum billable unit based on the currency for + the account. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + """ + + target_cpa_micros = proto.Field(proto.INT64, number=1, optional=True,) + + class TargetImpressionShare(proto.Message): + r"""An automated bidding strategy that sets bids so that a + certain percentage of search ads are shown at the top of the + first page (or other targeted location). + + Attributes: + location (google.ads.googleads.v12.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): + Output only. The targeted location on the + search results page. + location_fraction_micros (int): + The chosen fraction of ads to be shown in the + targeted location in micros. For example, 1% + equals 10,000. + + This field is a member of `oneof`_ ``_location_fraction_micros``. + cpc_bid_ceiling_micros (int): + Output only. The highest CPC bid the + automated bidding system is permitted to + specify. This is a required field entered by the + advertiser that sets the ceiling and specified + in local micros. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + """ + + location = proto.Field( + proto.ENUM, + number=1, + enum=target_impression_share_location.TargetImpressionShareLocationEnum.TargetImpressionShareLocation, + ) + location_fraction_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + cpc_bid_ceiling_micros = proto.Field( + proto.INT64, number=3, optional=True, + ) + + class TargetRoas(proto.Message): + r"""An automated bidding strategy that helps you maximize revenue + while averaging a specific target return on ad spend (ROAS). + + Attributes: + target_roas (float): + Output only. The chosen revenue (based on + conversion data) per unit of spend. + + This field is a member of `oneof`_ ``_target_roas``. + """ + + target_roas = proto.Field(proto.DOUBLE, number=1, optional=True,) + + class TargetSpend(proto.Message): + r"""An automated bid strategy that sets your bids to help get as + many clicks as possible within your budget. + + Attributes: + target_spend_micros (int): + Output only. The spend target under which to + maximize clicks. A TargetSpend bidder will + attempt to spend the smaller of this value or + the natural throttling spend amount. + If not specified, the budget is used as the + spend target. This field is deprecated and + should no longer be used. See + https://ads-developers.googleblog.com/2020/05/reminder-about-sunset-creation-of.html + for details. + + This field is a member of `oneof`_ ``_target_spend_micros``. + cpc_bid_ceiling_micros (int): + Output only. Maximum bid limit that can be + set by the bid strategy. The limit applies to + all keywords managed by the strategy. + + This field is a member of `oneof`_ ``_cpc_bid_ceiling_micros``. + """ + + target_spend_micros = proto.Field(proto.INT64, number=1, optional=True,) + cpc_bid_ceiling_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType, + ) + owner_customer_id = proto.Field(proto.INT64, number=5,) + owner_descriptive_name = proto.Field(proto.STRING, number=6,) + maximize_conversion_value = proto.Field( + proto.MESSAGE, + number=7, + oneof="scheme", + message=MaximizeConversionValue, + ) + maximize_conversions = proto.Field( + proto.MESSAGE, number=8, oneof="scheme", message=MaximizeConversions, + ) + target_cpa = proto.Field( + proto.MESSAGE, number=9, oneof="scheme", message=TargetCpa, + ) + target_impression_share = proto.Field( + proto.MESSAGE, number=10, oneof="scheme", message=TargetImpressionShare, + ) + target_roas = proto.Field( + proto.MESSAGE, number=11, oneof="scheme", message=TargetRoas, + ) + target_spend = proto.Field( + proto.MESSAGE, number=12, oneof="scheme", message=TargetSpend, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/account_budget.py b/google/ads/googleads/v12/resources/types/account_budget.py new file mode 100644 index 000000000..1b680d684 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/account_budget.py @@ -0,0 +1,374 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import account_budget_proposal_type +from google.ads.googleads.v12.enums.types import account_budget_status +from google.ads.googleads.v12.enums.types import ( + spending_limit_type as gage_spending_limit_type, +) +from google.ads.googleads.v12.enums.types import time_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AccountBudget",}, +) + + +class AccountBudget(proto.Message): + r"""An account-level budget. It contains information about the budget + itself, as well as the most recently approved changes to the budget + and proposed changes that are pending approval. The proposed changes + that are pending approval, if any, are found in 'pending_proposal'. + Effective details about the budget are found in fields prefixed + 'approved_', 'adjusted_' and those without a prefix. Since some + effective details may differ from what the user had originally + requested (for example, spending limit), these differences are + juxtaposed through 'proposed_', 'approved_', and possibly + 'adjusted_' fields. + + This resource is mutated using AccountBudgetProposal and cannot be + mutated directly. A budget may have at most one pending proposal at + any given time. It is read through pending_proposal. + + Once approved, a budget may be subject to adjustments, such as + credit adjustments. Adjustments create differences between the + 'approved' and 'adjusted' fields, which would otherwise be + identical. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the account-level budget. + AccountBudget resource names have the form: + + ``customers/{customer_id}/accountBudgets/{account_budget_id}`` + id (int): + Output only. The ID of the account-level + budget. + + This field is a member of `oneof`_ ``_id``. + billing_setup (str): + Output only. The resource name of the billing setup + associated with this account-level budget. BillingSetup + resource names have the form: + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + + This field is a member of `oneof`_ ``_billing_setup``. + status (google.ads.googleads.v12.enums.types.AccountBudgetStatusEnum.AccountBudgetStatus): + Output only. The status of this account-level + budget. + name (str): + Output only. The name of the account-level + budget. + + This field is a member of `oneof`_ ``_name``. + proposed_start_date_time (str): + Output only. The proposed start time of the + account-level budget in yyyy-MM-dd HH:mm:ss + format. If a start time type of NOW was + proposed, this is the time of request. + + This field is a member of `oneof`_ ``_proposed_start_date_time``. + approved_start_date_time (str): + Output only. The approved start time of the + account-level budget in yyyy-MM-dd HH:mm:ss + format. + For example, if a new budget is approved after + the proposed start time, the approved start time + is the time of approval. + + This field is a member of `oneof`_ ``_approved_start_date_time``. + total_adjustments_micros (int): + Output only. The total adjustments amount. + An example of an adjustment is courtesy credits. + amount_served_micros (int): + Output only. The value of Ads that have been served, in + micros. + + This includes overdelivery costs, in which case a credit + might be automatically applied to the budget (see + total_adjustments_micros). + purchase_order_number (str): + Output only. A purchase order number is a + value that helps users reference this budget in + their monthly invoices. + + This field is a member of `oneof`_ ``_purchase_order_number``. + notes (str): + Output only. Notes associated with the + budget. + + This field is a member of `oneof`_ ``_notes``. + pending_proposal (google.ads.googleads.v12.resources.types.AccountBudget.PendingAccountBudgetProposal): + Output only. The pending proposal to modify + this budget, if applicable. + proposed_end_date_time (str): + Output only. The proposed end time in + yyyy-MM-dd HH:mm:ss format. + + This field is a member of `oneof`_ ``proposed_end_time``. + proposed_end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Output only. The proposed end time as a + well-defined type, for example, FOREVER. + + This field is a member of `oneof`_ ``proposed_end_time``. + approved_end_date_time (str): + Output only. The approved end time in + yyyy-MM-dd HH:mm:ss format. + + This field is a member of `oneof`_ ``approved_end_time``. + approved_end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Output only. The approved end time as a + well-defined type, for example, FOREVER. + + This field is a member of `oneof`_ ``approved_end_time``. + proposed_spending_limit_micros (int): + Output only. The proposed spending limit in + micros. One million is equivalent to one unit. + + This field is a member of `oneof`_ ``proposed_spending_limit``. + proposed_spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Output only. The proposed spending limit as a + well-defined type, for example, INFINITE. + + This field is a member of `oneof`_ ``proposed_spending_limit``. + approved_spending_limit_micros (int): + Output only. The approved spending limit in + micros. One million is equivalent to one unit. + This will only be populated if the proposed + spending limit is finite, and will always be + greater than or equal to the proposed spending + limit. + + This field is a member of `oneof`_ ``approved_spending_limit``. + approved_spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Output only. The approved spending limit as a + well-defined type, for example, INFINITE. This + will only be populated if the approved spending + limit is INFINITE. + + This field is a member of `oneof`_ ``approved_spending_limit``. + adjusted_spending_limit_micros (int): + Output only. The adjusted spending limit in + micros. One million is equivalent to one unit. + If the approved spending limit is finite, the + adjusted spending limit may vary depending on + the types of adjustments applied to this budget, + if applicable. + + The different kinds of adjustments are described + here: + https://support.google.com/google-ads/answer/1704323 + For example, a debit adjustment reduces how much + the account is allowed to spend. + + This field is a member of `oneof`_ ``adjusted_spending_limit``. + adjusted_spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Output only. The adjusted spending limit as a + well-defined type, for example, INFINITE. This + will only be populated if the adjusted spending + limit is INFINITE, which is guaranteed to be + true if the approved spending limit is INFINITE. + + This field is a member of `oneof`_ ``adjusted_spending_limit``. + """ + + class PendingAccountBudgetProposal(proto.Message): + r"""A pending proposal associated with the enclosing + account-level budget, if applicable. + + 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: + account_budget_proposal (str): + Output only. The resource name of the proposal. + AccountBudgetProposal resource names have the form: + + ``customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}`` + + This field is a member of `oneof`_ ``_account_budget_proposal``. + proposal_type (google.ads.googleads.v12.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): + Output only. The type of this proposal, for + example, END to end the budget associated with + this proposal. + name (str): + Output only. The name to assign to the + account-level budget. + + This field is a member of `oneof`_ ``_name``. + start_date_time (str): + Output only. The start time in yyyy-MM-dd + HH:mm:ss format. + + This field is a member of `oneof`_ ``_start_date_time``. + purchase_order_number (str): + Output only. A purchase order number is a + value that helps users reference this budget in + their monthly invoices. + + This field is a member of `oneof`_ ``_purchase_order_number``. + notes (str): + Output only. Notes associated with this + budget. + + This field is a member of `oneof`_ ``_notes``. + creation_date_time (str): + Output only. The time when this account-level + budget proposal was created. Formatted as + yyyy-MM-dd HH:mm:ss. + + This field is a member of `oneof`_ ``_creation_date_time``. + end_date_time (str): + Output only. The end time in yyyy-MM-dd + HH:mm:ss format. + + This field is a member of `oneof`_ ``end_time``. + end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Output only. The end time as a well-defined + type, for example, FOREVER. + + This field is a member of `oneof`_ ``end_time``. + spending_limit_micros (int): + Output only. The spending limit in micros. + One million is equivalent to one unit. + + This field is a member of `oneof`_ ``spending_limit``. + spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Output only. The spending limit as a + well-defined type, for example, INFINITE. + + This field is a member of `oneof`_ ``spending_limit``. + """ + + account_budget_proposal = proto.Field( + proto.STRING, number=12, optional=True, + ) + proposal_type = proto.Field( + proto.ENUM, + number=2, + enum=account_budget_proposal_type.AccountBudgetProposalTypeEnum.AccountBudgetProposalType, + ) + name = proto.Field(proto.STRING, number=13, optional=True,) + start_date_time = proto.Field(proto.STRING, number=14, optional=True,) + purchase_order_number = proto.Field( + proto.STRING, number=17, optional=True, + ) + notes = proto.Field(proto.STRING, number=18, optional=True,) + creation_date_time = proto.Field( + proto.STRING, number=19, optional=True, + ) + end_date_time = proto.Field(proto.STRING, number=15, oneof="end_time",) + end_time_type = proto.Field( + proto.ENUM, + number=6, + oneof="end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + spending_limit_micros = proto.Field( + proto.INT64, number=16, oneof="spending_limit", + ) + spending_limit_type = proto.Field( + proto.ENUM, + number=8, + oneof="spending_limit", + enum=gage_spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=23, optional=True,) + billing_setup = proto.Field(proto.STRING, number=24, optional=True,) + status = proto.Field( + proto.ENUM, + number=4, + enum=account_budget_status.AccountBudgetStatusEnum.AccountBudgetStatus, + ) + name = proto.Field(proto.STRING, number=25, optional=True,) + proposed_start_date_time = proto.Field( + proto.STRING, number=26, optional=True, + ) + approved_start_date_time = proto.Field( + proto.STRING, number=27, optional=True, + ) + total_adjustments_micros = proto.Field(proto.INT64, number=33,) + amount_served_micros = proto.Field(proto.INT64, number=34,) + purchase_order_number = proto.Field(proto.STRING, number=35, optional=True,) + notes = proto.Field(proto.STRING, number=36, optional=True,) + pending_proposal = proto.Field( + proto.MESSAGE, number=22, message=PendingAccountBudgetProposal, + ) + proposed_end_date_time = proto.Field( + proto.STRING, number=28, oneof="proposed_end_time", + ) + proposed_end_time_type = proto.Field( + proto.ENUM, + number=9, + oneof="proposed_end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + approved_end_date_time = proto.Field( + proto.STRING, number=29, oneof="approved_end_time", + ) + approved_end_time_type = proto.Field( + proto.ENUM, + number=11, + oneof="approved_end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + proposed_spending_limit_micros = proto.Field( + proto.INT64, number=30, oneof="proposed_spending_limit", + ) + proposed_spending_limit_type = proto.Field( + proto.ENUM, + number=13, + oneof="proposed_spending_limit", + enum=gage_spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + approved_spending_limit_micros = proto.Field( + proto.INT64, number=31, oneof="approved_spending_limit", + ) + approved_spending_limit_type = proto.Field( + proto.ENUM, + number=15, + oneof="approved_spending_limit", + enum=gage_spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + adjusted_spending_limit_micros = proto.Field( + proto.INT64, number=32, oneof="adjusted_spending_limit", + ) + adjusted_spending_limit_type = proto.Field( + proto.ENUM, + number=17, + oneof="adjusted_spending_limit", + enum=gage_spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/account_budget_proposal.py b/google/ads/googleads/v12/resources/types/account_budget_proposal.py new file mode 100644 index 000000000..e546f66ed --- /dev/null +++ b/google/ads/googleads/v12/resources/types/account_budget_proposal.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import account_budget_proposal_status +from google.ads.googleads.v12.enums.types import account_budget_proposal_type +from google.ads.googleads.v12.enums.types import spending_limit_type +from google.ads.googleads.v12.enums.types import time_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AccountBudgetProposal",}, +) + + +class AccountBudgetProposal(proto.Message): + r"""An account-level budget proposal. + + All fields prefixed with 'proposed' may not necessarily be applied + directly. For example, proposed spending limits may be adjusted + before their application. This is true if the 'proposed' field has + an 'approved' counterpart, for example, spending limits. + + Note that the proposal type (proposal_type) changes which fields are + required and which must remain empty. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the proposal. + AccountBudgetProposal resource names have the form: + + ``customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}`` + id (int): + Output only. The ID of the proposal. + + This field is a member of `oneof`_ ``_id``. + billing_setup (str): + Immutable. The resource name of the billing + setup associated with this proposal. + + This field is a member of `oneof`_ ``_billing_setup``. + account_budget (str): + Immutable. The resource name of the + account-level budget associated with this + proposal. + + This field is a member of `oneof`_ ``_account_budget``. + proposal_type (google.ads.googleads.v12.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): + Immutable. The type of this proposal, for + example, END to end the budget associated with + this proposal. + status (google.ads.googleads.v12.enums.types.AccountBudgetProposalStatusEnum.AccountBudgetProposalStatus): + Output only. The status of this proposal. + When a new proposal is created, the status + defaults to PENDING. + proposed_name (str): + Immutable. The name to assign to the + account-level budget. + + This field is a member of `oneof`_ ``_proposed_name``. + approved_start_date_time (str): + Output only. The approved start date time in + yyyy-mm-dd hh:mm:ss format. + + This field is a member of `oneof`_ ``_approved_start_date_time``. + proposed_purchase_order_number (str): + Immutable. A purchase order number is a value + that enables the user to help them reference + this budget in their monthly invoices. + + This field is a member of `oneof`_ ``_proposed_purchase_order_number``. + proposed_notes (str): + Immutable. Notes associated with this budget. + + This field is a member of `oneof`_ ``_proposed_notes``. + creation_date_time (str): + Output only. The date time when this + account-level budget proposal was created, which + is not the same as its approval date time, if + applicable. + + This field is a member of `oneof`_ ``_creation_date_time``. + approval_date_time (str): + Output only. The date time when this + account-level budget was approved, if + applicable. + + This field is a member of `oneof`_ ``_approval_date_time``. + proposed_start_date_time (str): + Immutable. The proposed start date time in + yyyy-mm-dd hh:mm:ss format. + + This field is a member of `oneof`_ ``proposed_start_time``. + proposed_start_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Immutable. The proposed start date time as a + well-defined type, for example, NOW. + + This field is a member of `oneof`_ ``proposed_start_time``. + proposed_end_date_time (str): + Immutable. The proposed end date time in + yyyy-mm-dd hh:mm:ss format. + + This field is a member of `oneof`_ ``proposed_end_time``. + proposed_end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Immutable. The proposed end date time as a + well-defined type, for example, FOREVER. + + This field is a member of `oneof`_ ``proposed_end_time``. + approved_end_date_time (str): + Output only. The approved end date time in + yyyy-mm-dd hh:mm:ss format. + + This field is a member of `oneof`_ ``approved_end_time``. + approved_end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Output only. The approved end date time as a + well-defined type, for example, FOREVER. + + This field is a member of `oneof`_ ``approved_end_time``. + proposed_spending_limit_micros (int): + Immutable. The proposed spending limit in + micros. One million is equivalent to one unit. + + This field is a member of `oneof`_ ``proposed_spending_limit``. + proposed_spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Immutable. The proposed spending limit as a + well-defined type, for example, INFINITE. + + This field is a member of `oneof`_ ``proposed_spending_limit``. + approved_spending_limit_micros (int): + Output only. The approved spending limit in + micros. One million is equivalent to one unit. + + This field is a member of `oneof`_ ``approved_spending_limit``. + approved_spending_limit_type (google.ads.googleads.v12.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + Output only. The approved spending limit as a + well-defined type, for example, INFINITE. + + This field is a member of `oneof`_ ``approved_spending_limit``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=25, optional=True,) + billing_setup = proto.Field(proto.STRING, number=26, optional=True,) + account_budget = proto.Field(proto.STRING, number=27, optional=True,) + proposal_type = proto.Field( + proto.ENUM, + number=4, + enum=account_budget_proposal_type.AccountBudgetProposalTypeEnum.AccountBudgetProposalType, + ) + status = proto.Field( + proto.ENUM, + number=15, + enum=account_budget_proposal_status.AccountBudgetProposalStatusEnum.AccountBudgetProposalStatus, + ) + proposed_name = proto.Field(proto.STRING, number=28, optional=True,) + approved_start_date_time = proto.Field( + proto.STRING, number=30, optional=True, + ) + proposed_purchase_order_number = proto.Field( + proto.STRING, number=35, optional=True, + ) + proposed_notes = proto.Field(proto.STRING, number=36, optional=True,) + creation_date_time = proto.Field(proto.STRING, number=37, optional=True,) + approval_date_time = proto.Field(proto.STRING, number=38, optional=True,) + proposed_start_date_time = proto.Field( + proto.STRING, number=29, oneof="proposed_start_time", + ) + proposed_start_time_type = proto.Field( + proto.ENUM, + number=7, + oneof="proposed_start_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + proposed_end_date_time = proto.Field( + proto.STRING, number=31, oneof="proposed_end_time", + ) + proposed_end_time_type = proto.Field( + proto.ENUM, + number=9, + oneof="proposed_end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + approved_end_date_time = proto.Field( + proto.STRING, number=32, oneof="approved_end_time", + ) + approved_end_time_type = proto.Field( + proto.ENUM, + number=22, + oneof="approved_end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + proposed_spending_limit_micros = proto.Field( + proto.INT64, number=33, oneof="proposed_spending_limit", + ) + proposed_spending_limit_type = proto.Field( + proto.ENUM, + number=11, + oneof="proposed_spending_limit", + enum=spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + approved_spending_limit_micros = proto.Field( + proto.INT64, number=34, oneof="approved_spending_limit", + ) + approved_spending_limit_type = proto.Field( + proto.ENUM, + number=24, + oneof="approved_spending_limit", + enum=spending_limit_type.SpendingLimitTypeEnum.SpendingLimitType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/account_link.py b/google/ads/googleads/v12/resources/types/account_link.py new file mode 100644 index 000000000..842d582fc --- /dev/null +++ b/google/ads/googleads/v12/resources/types/account_link.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import account_link_status +from google.ads.googleads.v12.enums.types import linked_account_type +from google.ads.googleads.v12.enums.types import mobile_app_vendor + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={ + "AccountLink", + "ThirdPartyAppAnalyticsLinkIdentifier", + "DataPartnerLinkIdentifier", + "HotelCenterLinkIdentifier", + "GoogleAdsLinkIdentifier", + "AdvertisingPartnerLinkIdentifier", + }, +) + + +class AccountLink(proto.Message): + r"""Represents the data sharing connection between a Google Ads + account and another account + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. Resource name of the account link. AccountLink + resource names have the form: + ``customers/{customer_id}/accountLinks/{account_link_id}`` + account_link_id (int): + Output only. The ID of the link. + This field is read only. + + This field is a member of `oneof`_ ``_account_link_id``. + status (google.ads.googleads.v12.enums.types.AccountLinkStatusEnum.AccountLinkStatus): + The status of the link. + type_ (google.ads.googleads.v12.enums.types.LinkedAccountTypeEnum.LinkedAccountType): + Output only. The type of the linked account. + third_party_app_analytics (google.ads.googleads.v12.resources.types.ThirdPartyAppAnalyticsLinkIdentifier): + Immutable. A third party app analytics link. + + This field is a member of `oneof`_ ``linked_account``. + data_partner (google.ads.googleads.v12.resources.types.DataPartnerLinkIdentifier): + Output only. Data partner link. + + This field is a member of `oneof`_ ``linked_account``. + google_ads (google.ads.googleads.v12.resources.types.GoogleAdsLinkIdentifier): + Output only. Google Ads link. + + This field is a member of `oneof`_ ``linked_account``. + hotel_center (google.ads.googleads.v12.resources.types.HotelCenterLinkIdentifier): + Output only. Hotel link + + This field is a member of `oneof`_ ``linked_account``. + advertising_partner (google.ads.googleads.v12.resources.types.AdvertisingPartnerLinkIdentifier): + Output only. Advertising Partner link + + This field is a member of `oneof`_ ``linked_account``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + account_link_id = proto.Field(proto.INT64, number=8, optional=True,) + status = proto.Field( + proto.ENUM, + number=3, + enum=account_link_status.AccountLinkStatusEnum.AccountLinkStatus, + ) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=linked_account_type.LinkedAccountTypeEnum.LinkedAccountType, + ) + third_party_app_analytics = proto.Field( + proto.MESSAGE, + number=5, + oneof="linked_account", + message="ThirdPartyAppAnalyticsLinkIdentifier", + ) + data_partner = proto.Field( + proto.MESSAGE, + number=6, + oneof="linked_account", + message="DataPartnerLinkIdentifier", + ) + google_ads = proto.Field( + proto.MESSAGE, + number=7, + oneof="linked_account", + message="GoogleAdsLinkIdentifier", + ) + hotel_center = proto.Field( + proto.MESSAGE, + number=9, + oneof="linked_account", + message="HotelCenterLinkIdentifier", + ) + advertising_partner = proto.Field( + proto.MESSAGE, + number=10, + oneof="linked_account", + message="AdvertisingPartnerLinkIdentifier", + ) + + +class ThirdPartyAppAnalyticsLinkIdentifier(proto.Message): + r"""The identifiers of a Third Party App Analytics Link. + + Attributes: + app_analytics_provider_id (int): + Immutable. The ID of the app analytics + provider. This field should not be empty when + creating a new third party app analytics link. + It is unable to be modified after the creation + of the link. + + This field is a member of `oneof`_ ``_app_analytics_provider_id``. + app_id (str): + Immutable. A string that uniquely identifies + a mobile application from which the data was + collected to the Google Ads API. For iOS, the ID + string is the 9 digit string that appears at the + end of an App Store URL (for example, + "422689480" for "Gmail" whose App Store link is + https://apps.apple.com/us/app/gmail-email-by-google/id422689480). + For Android, the ID string is the application's + package name (for example, + "com.google.android.gm" for "Gmail" given Google + Play link + https://play.google.com/store/apps/details?id=com.google.android.gm) + This field should not be empty when creating a + new third party app analytics link. It is unable + to be modified after the creation of the link. + + This field is a member of `oneof`_ ``_app_id``. + app_vendor (google.ads.googleads.v12.enums.types.MobileAppVendorEnum.MobileAppVendor): + Immutable. The vendor of the app. + This field should not be empty when creating a + new third party app analytics link. It is unable + to be modified after the creation of the link. + """ + + app_analytics_provider_id = proto.Field( + proto.INT64, number=4, optional=True, + ) + app_id = proto.Field(proto.STRING, number=5, optional=True,) + app_vendor = proto.Field( + proto.ENUM, + number=3, + enum=mobile_app_vendor.MobileAppVendorEnum.MobileAppVendor, + ) + + +class DataPartnerLinkIdentifier(proto.Message): + r"""The identifier for Data Partner account. + + Attributes: + data_partner_id (int): + Immutable. The customer ID of the Data + partner account. This field is required and + should not be empty when creating a new data + partner link. It is unable to be modified after + the creation of the link. + + This field is a member of `oneof`_ ``_data_partner_id``. + """ + + data_partner_id = proto.Field(proto.INT64, number=1, optional=True,) + + +class HotelCenterLinkIdentifier(proto.Message): + r"""The identifier for Hotel account. + + Attributes: + hotel_center_id (int): + Output only. The hotel center id of the hotel + account. + """ + + hotel_center_id = proto.Field(proto.INT64, number=1,) + + +class GoogleAdsLinkIdentifier(proto.Message): + r"""The identifier for Google Ads account. + + Attributes: + customer (str): + Immutable. The resource name of the Google + Ads account. This field is required and should + not be empty when creating a new Google Ads + link. It is unable to be modified after the + creation of the link. + + This field is a member of `oneof`_ ``_customer``. + """ + + customer = proto.Field(proto.STRING, number=3, optional=True,) + + +class AdvertisingPartnerLinkIdentifier(proto.Message): + r"""The identifier for the Advertising Partner Google Ads + account. + + Attributes: + customer (str): + Immutable. The resource name of the + advertising partner Google Ads account. This + field is required and should not be empty when + creating a new Advertising Partner link. It is + unable to be modified after the creation of the + link. + + This field is a member of `oneof`_ ``_customer``. + """ + + customer = proto.Field(proto.STRING, number=1, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad.py b/google/ads/googleads/v12/resources/types/ad.py new file mode 100644 index 000000000..dab87f045 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ad_type_infos +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import final_app_url +from google.ads.googleads.v12.common.types import url_collection +from google.ads.googleads.v12.enums.types import ad_type +from google.ads.googleads.v12.enums.types import device +from google.ads.googleads.v12.enums.types import system_managed_entity_source + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Ad",}, +) + + +class Ad(proto.Message): + r"""An ad. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the ad. Ad resource names + have the form: + + ``customers/{customer_id}/ads/{ad_id}`` + id (int): + Output only. The ID of the ad. + + This field is a member of `oneof`_ ``_id``. + final_urls (Sequence[str]): + The list of possible final URLs after all + cross-domain redirects for the ad. + final_app_urls (Sequence[google.ads.googleads.v12.common.types.FinalAppUrl]): + A list of final app URLs that will be used on + mobile if the user has the specific app + installed. + final_mobile_urls (Sequence[str]): + The list of possible final mobile URLs after + all cross-domain redirects for the ad. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + final_url_suffix (str): + The suffix to use when constructing a final + URL. + + This field is a member of `oneof`_ ``_final_url_suffix``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + The list of mappings that can be used to substitute custom + parameter tags in a ``tracking_url_template``, + ``final_urls``, or ``mobile_final_urls``. For mutates, use + url custom parameter operations. + display_url (str): + The URL that appears in the ad description + for some ad formats. + + This field is a member of `oneof`_ ``_display_url``. + type_ (google.ads.googleads.v12.enums.types.AdTypeEnum.AdType): + Output only. The type of ad. + added_by_google_ads (bool): + Output only. Indicates if this ad was + automatically added by Google Ads and not by a + user. For example, this could happen when ads + are automatically created as suggestions for new + ads based on knowledge of how existing ads are + performing. + + This field is a member of `oneof`_ ``_added_by_google_ads``. + device_preference (google.ads.googleads.v12.enums.types.DeviceEnum.Device): + The device preference for the ad. You can + only specify a preference for mobile devices. + When this preference is set the ad will be + preferred over other ads when being displayed on + a mobile device. The ad can still be displayed + on other device types, for example, if no other + ads are available. If unspecified (no device + preference), all devices are targeted. This is + only supported by some ad types. + url_collections (Sequence[google.ads.googleads.v12.common.types.UrlCollection]): + Additional URLs for the ad that are tagged + with a unique identifier that can be referenced + from other fields in the ad. + name (str): + Immutable. The name of the ad. This is only + used to be able to identify the ad. It does not + need to be unique and does not affect the served + ad. The name field is currently only supported + for DisplayUploadAd, ImageAd, + ShoppingComparisonListingAd and VideoAd. + + This field is a member of `oneof`_ ``_name``. + system_managed_resource_source (google.ads.googleads.v12.enums.types.SystemManagedResourceSourceEnum.SystemManagedResourceSource): + Output only. If this ad is system managed, + then this field will indicate the source. This + field is read-only. + text_ad (google.ads.googleads.v12.common.types.TextAdInfo): + Immutable. Details pertaining to a text ad. + + This field is a member of `oneof`_ ``ad_data``. + expanded_text_ad (google.ads.googleads.v12.common.types.ExpandedTextAdInfo): + Details pertaining to an expanded text ad. + + This field is a member of `oneof`_ ``ad_data``. + call_ad (google.ads.googleads.v12.common.types.CallAdInfo): + Details pertaining to a call ad. + + This field is a member of `oneof`_ ``ad_data``. + expanded_dynamic_search_ad (google.ads.googleads.v12.common.types.ExpandedDynamicSearchAdInfo): + Immutable. Details pertaining to an Expanded Dynamic Search + Ad. This type of ad has its headline, final URLs, and + display URL auto-generated at serving time according to + domain name specific information provided by + ``dynamic_search_ads_setting`` linked at the campaign level. + + This field is a member of `oneof`_ ``ad_data``. + hotel_ad (google.ads.googleads.v12.common.types.HotelAdInfo): + Details pertaining to a hotel ad. + + This field is a member of `oneof`_ ``ad_data``. + shopping_smart_ad (google.ads.googleads.v12.common.types.ShoppingSmartAdInfo): + Details pertaining to a Smart Shopping ad. + + This field is a member of `oneof`_ ``ad_data``. + shopping_product_ad (google.ads.googleads.v12.common.types.ShoppingProductAdInfo): + Details pertaining to a Shopping product ad. + + This field is a member of `oneof`_ ``ad_data``. + image_ad (google.ads.googleads.v12.common.types.ImageAdInfo): + Immutable. Details pertaining to an Image ad. + + This field is a member of `oneof`_ ``ad_data``. + video_ad (google.ads.googleads.v12.common.types.VideoAdInfo): + Details pertaining to a Video ad. + + This field is a member of `oneof`_ ``ad_data``. + video_responsive_ad (google.ads.googleads.v12.common.types.VideoResponsiveAdInfo): + Details pertaining to a Video responsive ad. + + This field is a member of `oneof`_ ``ad_data``. + responsive_search_ad (google.ads.googleads.v12.common.types.ResponsiveSearchAdInfo): + Details pertaining to a responsive search ad. + + This field is a member of `oneof`_ ``ad_data``. + legacy_responsive_display_ad (google.ads.googleads.v12.common.types.LegacyResponsiveDisplayAdInfo): + Details pertaining to a legacy responsive + display ad. + + This field is a member of `oneof`_ ``ad_data``. + app_ad (google.ads.googleads.v12.common.types.AppAdInfo): + Details pertaining to an app ad. + + This field is a member of `oneof`_ ``ad_data``. + legacy_app_install_ad (google.ads.googleads.v12.common.types.LegacyAppInstallAdInfo): + Immutable. Details pertaining to a legacy app + install ad. + + This field is a member of `oneof`_ ``ad_data``. + responsive_display_ad (google.ads.googleads.v12.common.types.ResponsiveDisplayAdInfo): + Details pertaining to a responsive display + ad. + + This field is a member of `oneof`_ ``ad_data``. + local_ad (google.ads.googleads.v12.common.types.LocalAdInfo): + Details pertaining to a local ad. + + This field is a member of `oneof`_ ``ad_data``. + display_upload_ad (google.ads.googleads.v12.common.types.DisplayUploadAdInfo): + Details pertaining to a display upload ad. + + This field is a member of `oneof`_ ``ad_data``. + app_engagement_ad (google.ads.googleads.v12.common.types.AppEngagementAdInfo): + Details pertaining to an app engagement ad. + + This field is a member of `oneof`_ ``ad_data``. + shopping_comparison_listing_ad (google.ads.googleads.v12.common.types.ShoppingComparisonListingAdInfo): + Details pertaining to a Shopping Comparison + Listing ad. + + This field is a member of `oneof`_ ``ad_data``. + smart_campaign_ad (google.ads.googleads.v12.common.types.SmartCampaignAdInfo): + Details pertaining to a Smart campaign ad. + + This field is a member of `oneof`_ ``ad_data``. + app_pre_registration_ad (google.ads.googleads.v12.common.types.AppPreRegistrationAdInfo): + Details pertaining to an app pre-registration + ad. + + This field is a member of `oneof`_ ``ad_data``. + discovery_multi_asset_ad (google.ads.googleads.v12.common.types.DiscoveryMultiAssetAdInfo): + Details pertaining to a discovery multi asset + ad. + + This field is a member of `oneof`_ ``ad_data``. + discovery_carousel_ad (google.ads.googleads.v12.common.types.DiscoveryCarouselAdInfo): + Details pertaining to a discovery carousel + ad. + + This field is a member of `oneof`_ ``ad_data``. + """ + + resource_name = proto.Field(proto.STRING, number=37,) + id = proto.Field(proto.INT64, number=40, optional=True,) + final_urls = proto.RepeatedField(proto.STRING, number=41,) + final_app_urls = proto.RepeatedField( + proto.MESSAGE, number=35, message=final_app_url.FinalAppUrl, + ) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=42,) + tracking_url_template = proto.Field(proto.STRING, number=43, optional=True,) + final_url_suffix = proto.Field(proto.STRING, number=44, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=10, message=custom_parameter.CustomParameter, + ) + display_url = proto.Field(proto.STRING, number=45, optional=True,) + type_ = proto.Field(proto.ENUM, number=5, enum=ad_type.AdTypeEnum.AdType,) + added_by_google_ads = proto.Field(proto.BOOL, number=46, optional=True,) + device_preference = proto.Field( + proto.ENUM, number=20, enum=device.DeviceEnum.Device, + ) + url_collections = proto.RepeatedField( + proto.MESSAGE, number=26, message=url_collection.UrlCollection, + ) + name = proto.Field(proto.STRING, number=47, optional=True,) + system_managed_resource_source = proto.Field( + proto.ENUM, + number=27, + enum=system_managed_entity_source.SystemManagedResourceSourceEnum.SystemManagedResourceSource, + ) + text_ad = proto.Field( + proto.MESSAGE, + number=6, + oneof="ad_data", + message=ad_type_infos.TextAdInfo, + ) + expanded_text_ad = proto.Field( + proto.MESSAGE, + number=7, + oneof="ad_data", + message=ad_type_infos.ExpandedTextAdInfo, + ) + call_ad = proto.Field( + proto.MESSAGE, + number=49, + oneof="ad_data", + message=ad_type_infos.CallAdInfo, + ) + expanded_dynamic_search_ad = proto.Field( + proto.MESSAGE, + number=14, + oneof="ad_data", + message=ad_type_infos.ExpandedDynamicSearchAdInfo, + ) + hotel_ad = proto.Field( + proto.MESSAGE, + number=15, + oneof="ad_data", + message=ad_type_infos.HotelAdInfo, + ) + shopping_smart_ad = proto.Field( + proto.MESSAGE, + number=17, + oneof="ad_data", + message=ad_type_infos.ShoppingSmartAdInfo, + ) + shopping_product_ad = proto.Field( + proto.MESSAGE, + number=18, + oneof="ad_data", + message=ad_type_infos.ShoppingProductAdInfo, + ) + image_ad = proto.Field( + proto.MESSAGE, + number=22, + oneof="ad_data", + message=ad_type_infos.ImageAdInfo, + ) + video_ad = proto.Field( + proto.MESSAGE, + number=24, + oneof="ad_data", + message=ad_type_infos.VideoAdInfo, + ) + video_responsive_ad = proto.Field( + proto.MESSAGE, + number=39, + oneof="ad_data", + message=ad_type_infos.VideoResponsiveAdInfo, + ) + responsive_search_ad = proto.Field( + proto.MESSAGE, + number=25, + oneof="ad_data", + message=ad_type_infos.ResponsiveSearchAdInfo, + ) + legacy_responsive_display_ad = proto.Field( + proto.MESSAGE, + number=28, + oneof="ad_data", + message=ad_type_infos.LegacyResponsiveDisplayAdInfo, + ) + app_ad = proto.Field( + proto.MESSAGE, + number=29, + oneof="ad_data", + message=ad_type_infos.AppAdInfo, + ) + legacy_app_install_ad = proto.Field( + proto.MESSAGE, + number=30, + oneof="ad_data", + message=ad_type_infos.LegacyAppInstallAdInfo, + ) + responsive_display_ad = proto.Field( + proto.MESSAGE, + number=31, + oneof="ad_data", + message=ad_type_infos.ResponsiveDisplayAdInfo, + ) + local_ad = proto.Field( + proto.MESSAGE, + number=32, + oneof="ad_data", + message=ad_type_infos.LocalAdInfo, + ) + display_upload_ad = proto.Field( + proto.MESSAGE, + number=33, + oneof="ad_data", + message=ad_type_infos.DisplayUploadAdInfo, + ) + app_engagement_ad = proto.Field( + proto.MESSAGE, + number=34, + oneof="ad_data", + message=ad_type_infos.AppEngagementAdInfo, + ) + shopping_comparison_listing_ad = proto.Field( + proto.MESSAGE, + number=36, + oneof="ad_data", + message=ad_type_infos.ShoppingComparisonListingAdInfo, + ) + smart_campaign_ad = proto.Field( + proto.MESSAGE, + number=48, + oneof="ad_data", + message=ad_type_infos.SmartCampaignAdInfo, + ) + app_pre_registration_ad = proto.Field( + proto.MESSAGE, + number=50, + oneof="ad_data", + message=ad_type_infos.AppPreRegistrationAdInfo, + ) + discovery_multi_asset_ad = proto.Field( + proto.MESSAGE, + number=51, + oneof="ad_data", + message=ad_type_infos.DiscoveryMultiAssetAdInfo, + ) + discovery_carousel_ad = proto.Field( + proto.MESSAGE, + number=52, + oneof="ad_data", + message=ad_type_infos.DiscoveryCarouselAdInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group.py b/google/ads/googleads/v12/resources/types/ad_group.py new file mode 100644 index 000000000..9c14e188e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import ( + explorer_auto_optimizer_setting as gagc_explorer_auto_optimizer_setting, +) +from google.ads.googleads.v12.common.types import ( + targeting_setting as gagc_targeting_setting, +) +from google.ads.googleads.v12.enums.types import ad_group_ad_rotation_mode +from google.ads.googleads.v12.enums.types import ad_group_status +from google.ads.googleads.v12.enums.types import ad_group_type +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_set_type +from google.ads.googleads.v12.enums.types import bidding_source +from google.ads.googleads.v12.enums.types import targeting_dimension + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroup",}, +) + + +class AdGroup(proto.Message): + r"""An ad group. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group. Ad group + resource names have the form: + + ``customers/{customer_id}/adGroups/{ad_group_id}`` + id (int): + Output only. The ID of the ad group. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the ad group. + This field is required and should not be empty + when creating new ad groups. + + It must contain fewer than 255 UTF-8 full-width + characters. + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v12.enums.types.AdGroupStatusEnum.AdGroupStatus): + The status of the ad group. + type_ (google.ads.googleads.v12.enums.types.AdGroupTypeEnum.AdGroupType): + Immutable. The type of the ad group. + ad_rotation_mode (google.ads.googleads.v12.enums.types.AdGroupAdRotationModeEnum.AdGroupAdRotationMode): + The ad rotation mode of the ad group. + base_ad_group (str): + Output only. For draft or experiment ad + groups, this field is the resource name of the + base ad group from which this ad group was + created. If a draft or experiment ad group does + not have a base ad group, then this field is + null. + For base ad groups, this field equals the ad + group resource name. + This field is read-only. + + This field is a member of `oneof`_ ``_base_ad_group``. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + campaign (str): + Immutable. The campaign to which the ad group + belongs. + + This field is a member of `oneof`_ ``_campaign``. + cpc_bid_micros (int): + The maximum CPC (cost-per-click) bid. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + effective_cpc_bid_micros (int): + Output only. Value will be same as that of + the CPC (cost-per-click) bid value when the + bidding strategy is one of manual cpc, enhanced + cpc, page one promoted or target outrank share, + otherwise the value will be null. + + This field is a member of `oneof`_ ``_effective_cpc_bid_micros``. + cpm_bid_micros (int): + The maximum CPM (cost-per-thousand viewable + impressions) bid. + + This field is a member of `oneof`_ ``_cpm_bid_micros``. + target_cpa_micros (int): + The target CPA (cost-per-acquisition). If the ad group's + campaign bidding strategy is TargetCpa or + MaximizeConversions (with its target_cpa field set), then + this field overrides the target CPA specified in the + campaign's bidding strategy. Otherwise, this value is + ignored. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + cpv_bid_micros (int): + The CPV (cost-per-view) bid. + + This field is a member of `oneof`_ ``_cpv_bid_micros``. + target_cpm_micros (int): + Average amount in micros that the advertiser + is willing to pay for every thousand times the + ad is shown. + + This field is a member of `oneof`_ ``_target_cpm_micros``. + target_roas (float): + The target ROAS (return-on-ad-spend) override. If the ad + group's campaign bidding strategy is TargetRoas or + MaximizeConversionValue (with its target_roas field set), + then this field overrides the target ROAS specified in the + campaign's bidding strategy. Otherwise, this value is + ignored. + + This field is a member of `oneof`_ ``_target_roas``. + percent_cpc_bid_micros (int): + The percent cpc bid amount, expressed as a fraction of the + advertised price for some good or service. The valid range + for the fraction is [0,1) and the value stored here is + 1,000,000 \* [fraction]. + + This field is a member of `oneof`_ ``_percent_cpc_bid_micros``. + explorer_auto_optimizer_setting (google.ads.googleads.v12.common.types.ExplorerAutoOptimizerSetting): + Settings for the Display Campaign Optimizer, + initially termed "Explorer". + display_custom_bid_dimension (google.ads.googleads.v12.enums.types.TargetingDimensionEnum.TargetingDimension): + Allows advertisers to specify a targeting + dimension on which to place absolute bids. This + is only applicable for campaigns that target + only the display network and not search. + final_url_suffix (str): + URL template for appending params to Final + URL. + + This field is a member of `oneof`_ ``_final_url_suffix``. + targeting_setting (google.ads.googleads.v12.common.types.TargetingSetting): + Setting for targeting related features. + audience_setting (google.ads.googleads.v12.resources.types.AdGroup.AudienceSetting): + Immutable. Setting for audience related + features. + effective_target_cpa_micros (int): + Output only. The effective target CPA + (cost-per-acquisition). This field is read-only. + + This field is a member of `oneof`_ ``_effective_target_cpa_micros``. + effective_target_cpa_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective target + CPA. This field is read-only. + effective_target_roas (float): + Output only. The effective target ROAS + (return-on-ad-spend). This field is read-only. + + This field is a member of `oneof`_ ``_effective_target_roas``. + effective_target_roas_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective target + ROAS. This field is read-only. + labels (Sequence[str]): + Output only. The resource names of labels + attached to this ad group. + excluded_parent_asset_field_types (Sequence[google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType]): + The asset field types that should be excluded + from this ad group. Asset links with these field + types will not be inherited by this ad group + from the upper levels. + excluded_parent_asset_set_types (Sequence[google.ads.googleads.v12.enums.types.AssetSetTypeEnum.AssetSetType]): + The asset set types that should be excluded from this ad + group. Asset set links with these types will not be + inherited by this ad group from the upper levels. Location + group types (GMB_DYNAMIC_LOCATION_GROUP, + CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are + child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is + set for this field, all location group asset sets are not + allowed to be linked to this ad group, and all Location + Extension (LE) and Affiliate Location Extensions (ALE) will + not be served under this ad group. Only LOCATION_SYNC is + currently supported. + """ + + class AudienceSetting(proto.Message): + r"""Settings for the audience targeting. + + Attributes: + use_audience_grouped (bool): + Immutable. If true, this ad group uses an + Audience resource for audience targeting. If + false, this ad group may use audience segment + criteria instead. + """ + + use_audience_grouped = proto.Field(proto.BOOL, number=1,) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=34, optional=True,) + name = proto.Field(proto.STRING, number=35, optional=True,) + status = proto.Field( + proto.ENUM, + number=5, + enum=ad_group_status.AdGroupStatusEnum.AdGroupStatus, + ) + type_ = proto.Field( + proto.ENUM, number=12, enum=ad_group_type.AdGroupTypeEnum.AdGroupType, + ) + ad_rotation_mode = proto.Field( + proto.ENUM, + number=22, + enum=ad_group_ad_rotation_mode.AdGroupAdRotationModeEnum.AdGroupAdRotationMode, + ) + base_ad_group = proto.Field(proto.STRING, number=36, optional=True,) + tracking_url_template = proto.Field(proto.STRING, number=37, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=6, message=custom_parameter.CustomParameter, + ) + campaign = proto.Field(proto.STRING, number=38, optional=True,) + cpc_bid_micros = proto.Field(proto.INT64, number=39, optional=True,) + effective_cpc_bid_micros = proto.Field( + proto.INT64, number=57, optional=True, + ) + cpm_bid_micros = proto.Field(proto.INT64, number=40, optional=True,) + target_cpa_micros = proto.Field(proto.INT64, number=41, optional=True,) + cpv_bid_micros = proto.Field(proto.INT64, number=42, optional=True,) + target_cpm_micros = proto.Field(proto.INT64, number=43, optional=True,) + target_roas = proto.Field(proto.DOUBLE, number=44, optional=True,) + percent_cpc_bid_micros = proto.Field(proto.INT64, number=45, optional=True,) + explorer_auto_optimizer_setting = proto.Field( + proto.MESSAGE, + number=21, + message=gagc_explorer_auto_optimizer_setting.ExplorerAutoOptimizerSetting, + ) + display_custom_bid_dimension = proto.Field( + proto.ENUM, + number=23, + enum=targeting_dimension.TargetingDimensionEnum.TargetingDimension, + ) + final_url_suffix = proto.Field(proto.STRING, number=46, optional=True,) + targeting_setting = proto.Field( + proto.MESSAGE, + number=25, + message=gagc_targeting_setting.TargetingSetting, + ) + audience_setting = proto.Field( + proto.MESSAGE, number=56, message=AudienceSetting, + ) + effective_target_cpa_micros = proto.Field( + proto.INT64, number=47, optional=True, + ) + effective_target_cpa_source = proto.Field( + proto.ENUM, + number=29, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_target_roas = proto.Field(proto.DOUBLE, number=48, optional=True,) + effective_target_roas_source = proto.Field( + proto.ENUM, + number=32, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + labels = proto.RepeatedField(proto.STRING, number=49,) + excluded_parent_asset_field_types = proto.RepeatedField( + proto.ENUM, + number=54, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + excluded_parent_asset_set_types = proto.RepeatedField( + proto.ENUM, + number=58, + enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_ad.py b/google/ads/googleads/v12/resources/types/ad_group_ad.py new file mode 100644 index 000000000..b282b4670 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_ad.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import ad_group_ad_status +from google.ads.googleads.v12.enums.types import ad_strength as gage_ad_strength +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status +from google.ads.googleads.v12.resources.types import ad as gagr_ad + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAd", "AdGroupAdPolicySummary",}, +) + + +class AdGroupAd(proto.Message): + r"""An ad group ad. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad. Ad group ad resource + names have the form: + + ``customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}`` + status (google.ads.googleads.v12.enums.types.AdGroupAdStatusEnum.AdGroupAdStatus): + The status of the ad. + ad_group (str): + Immutable. The ad group to which the ad + belongs. + + This field is a member of `oneof`_ ``_ad_group``. + ad (google.ads.googleads.v12.resources.types.Ad): + Immutable. The ad. + policy_summary (google.ads.googleads.v12.resources.types.AdGroupAdPolicySummary): + Output only. Policy information for the ad. + ad_strength (google.ads.googleads.v12.enums.types.AdStrengthEnum.AdStrength): + Output only. Overall ad strength for this ad + group ad. + action_items (Sequence[str]): + Output only. A list of recommendations to + improve the ad strength. For example, a + recommendation could be "Your headlines are a + little too similar. Try adding more distinct + headlines.". + labels (Sequence[str]): + Output only. The resource names of labels + attached to this ad group ad. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + status = proto.Field( + proto.ENUM, + number=3, + enum=ad_group_ad_status.AdGroupAdStatusEnum.AdGroupAdStatus, + ) + ad_group = proto.Field(proto.STRING, number=9, optional=True,) + ad = proto.Field(proto.MESSAGE, number=5, message=gagr_ad.Ad,) + policy_summary = proto.Field( + proto.MESSAGE, number=6, message="AdGroupAdPolicySummary", + ) + ad_strength = proto.Field( + proto.ENUM, number=7, enum=gage_ad_strength.AdStrengthEnum.AdStrength, + ) + action_items = proto.RepeatedField(proto.STRING, number=13,) + labels = proto.RepeatedField(proto.STRING, number=10,) + + +class AdGroupAdPolicySummary(proto.Message): + r"""Contains policy information for an ad. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + Output only. The list of policy findings for + this ad. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Output only. Where in the review process this + ad is. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + Output only. The overall approval status of + this ad, calculated based on the status of its + individual policy topic entries. + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + review_status = proto.Field( + proto.ENUM, + number=2, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_ad_asset_combination_view.py b/google/ads/googleads/v12/resources/types/ad_group_ad_asset_combination_view.py new file mode 100644 index 000000000..f1d9ab468 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_ad_asset_combination_view.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import asset_usage + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdAssetCombinationView",}, +) + + +class AdGroupAdAssetCombinationView(proto.Message): + r"""A view on the usage of ad group ad asset combination. + Now we only support AdGroupAdAssetCombinationView for Responsive + Search Ads, with more ad types planned for the future. + + Attributes: + resource_name (str): + Output only. The resource name of the ad group ad asset + combination view. The combination ID is 128 bits long, where + the upper 64 bits are stored in asset_combination_id_high, + and the lower 64 bits are stored in + asset_combination_id_low. AdGroupAd Asset Combination view + resource names have the form: + ``customers/{customer_id}/adGroupAdAssetCombinationViews/{AdGroupAd.ad_group_id}~{AdGroupAd.ad.ad_id}~{AssetCombination.asset_combination_id_low}~{AssetCombination.asset_combination_id_high}`` + served_assets (Sequence[google.ads.googleads.v12.common.types.AssetUsage]): + Output only. Served assets. + enabled (bool): + Output only. The status between the asset + combination and the latest version of the ad. If + true, the asset combination is linked to the + latest version of the ad. If false, it means the + link once existed but has been removed and is no + longer present in the latest version of the ad. + + This field is a member of `oneof`_ ``_enabled``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + served_assets = proto.RepeatedField( + proto.MESSAGE, number=2, message=asset_usage.AssetUsage, + ) + enabled = proto.Field(proto.BOOL, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_ad_asset_view.py b/google/ads/googleads/v12/resources/types/ad_group_ad_asset_view.py new file mode 100644 index 000000000..515ca7f57 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_ad_asset_view.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_performance_label +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status +from google.ads.googleads.v12.enums.types import served_asset_field_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdAssetView", "AdGroupAdAssetPolicySummary",}, +) + + +class AdGroupAdAssetView(proto.Message): + r"""A link between an AdGroupAd and an Asset. + Currently we only support AdGroupAdAssetView for AppAds and + Responsive Search Ads. + + Attributes: + resource_name (str): + Output only. The resource name of the ad group ad asset + view. Ad group ad asset view resource names have the form + (Before V4): + + ``customers/{customer_id}/adGroupAdAssets/{AdGroupAdAsset.ad_group_id}~{AdGroupAdAsset.ad.ad_id}~{AdGroupAdAsset.asset_id}~{AdGroupAdAsset.field_type}`` + + Ad group ad asset view resource names have the form + (Beginning from V4): + + ``customers/{customer_id}/adGroupAdAssetViews/{AdGroupAdAsset.ad_group_id}~{AdGroupAdAsset.ad_id}~{AdGroupAdAsset.asset_id}~{AdGroupAdAsset.field_type}`` + ad_group_ad (str): + Output only. The ad group ad to which the + asset is linked. + + This field is a member of `oneof`_ ``_ad_group_ad``. + asset (str): + Output only. The asset which is linked to the + ad group ad. + + This field is a member of `oneof`_ ``_asset``. + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + Output only. Role that the asset takes in the + ad. + enabled (bool): + Output only. The status between the asset and + the latest version of the ad. If true, the asset + is linked to the latest version of the ad. If + false, it means the link once existed but has + been removed and is no longer present in the + latest version of the ad. + + This field is a member of `oneof`_ ``_enabled``. + policy_summary (google.ads.googleads.v12.resources.types.AdGroupAdAssetPolicySummary): + Output only. Policy information for the ad + group ad asset. + performance_label (google.ads.googleads.v12.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): + Output only. Performance of an asset linkage. + pinned_field (google.ads.googleads.v12.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + Output only. Pinned field. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_ad = proto.Field(proto.STRING, number=9, optional=True,) + asset = proto.Field(proto.STRING, number=10, optional=True,) + field_type = proto.Field( + proto.ENUM, + number=2, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + enabled = proto.Field(proto.BOOL, number=8, optional=True,) + policy_summary = proto.Field( + proto.MESSAGE, number=3, message="AdGroupAdAssetPolicySummary", + ) + performance_label = proto.Field( + proto.ENUM, + number=4, + enum=asset_performance_label.AssetPerformanceLabelEnum.AssetPerformanceLabel, + ) + pinned_field = proto.Field( + proto.ENUM, + number=11, + enum=served_asset_field_type.ServedAssetFieldTypeEnum.ServedAssetFieldType, + ) + + +class AdGroupAdAssetPolicySummary(proto.Message): + r"""Contains policy information for an ad group ad asset. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + Output only. The list of policy findings for + the ad group ad asset. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Output only. Where in the review process this + ad group ad asset is. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + Output only. The overall approval status of + this ad group ad asset, calculated based on the + status of its individual policy topic entries. + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + review_status = proto.Field( + proto.ENUM, + number=2, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_ad_label.py b/google/ads/googleads/v12/resources/types/ad_group_ad_label.py new file mode 100644 index 000000000..c0f0cbe6e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_ad_label.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAdLabel",}, +) + + +class AdGroupAdLabel(proto.Message): + r"""A relationship between an ad group ad and a label. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group ad label. Ad + group ad label resource names have the form: + ``customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}`` + ad_group_ad (str): + Immutable. The ad group ad to which the label + is attached. + + This field is a member of `oneof`_ ``_ad_group_ad``. + label (str): + Immutable. The label assigned to the ad group + ad. + + This field is a member of `oneof`_ ``_label``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_ad = proto.Field(proto.STRING, number=4, optional=True,) + label = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_asset.py b/google/ads/googleads/v12/resources/types/ad_group_asset.py new file mode 100644 index 000000000..43378d87a --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_asset.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_link_status +from google.ads.googleads.v12.enums.types import asset_source + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAsset",}, +) + + +class AdGroupAsset(proto.Message): + r"""A link between an ad group and an asset. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group asset. + AdGroupAsset resource names have the form: + + ``customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}`` + ad_group (str): + Required. Immutable. The ad group to which + the asset is linked. + asset (str): + Required. Immutable. The asset which is + linked to the ad group. + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + Required. Immutable. Role that the asset + takes under the linked ad group. + source (google.ads.googleads.v12.enums.types.AssetSourceEnum.AssetSource): + Output only. Source of the adgroup asset + link. + status (google.ads.googleads.v12.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + Status of the ad group asset. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field(proto.STRING, number=2,) + asset = proto.Field(proto.STRING, number=3,) + field_type = proto.Field( + proto.ENUM, + number=4, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + source = proto.Field( + proto.ENUM, number=6, enum=asset_source.AssetSourceEnum.AssetSource, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=asset_link_status.AssetLinkStatusEnum.AssetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_asset_set.py b/google/ads/googleads/v12/resources/types/ad_group_asset_set.py new file mode 100644 index 000000000..bff5a3535 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_asset_set.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_set_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAssetSet",}, +) + + +class AdGroupAssetSet(proto.Message): + r"""AdGroupAssetSet is the linkage between an ad group and an + asset set. Creating an AdGroupAssetSet links an asset set with + an ad group. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group asset set. Ad + group asset set resource names have the form: + + ``customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}`` + ad_group (str): + Immutable. The ad group to which this asset + set is linked. + asset_set (str): + Immutable. The asset set which is linked to + the ad group. + status (google.ads.googleads.v12.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + Output only. The status of the ad group asset + set. Read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field(proto.STRING, number=2,) + asset_set = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_set_link_status.AssetSetLinkStatusEnum.AssetSetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_audience_view.py b/google/ads/googleads/v12/resources/types/ad_group_audience_view.py new file mode 100644 index 000000000..28c3d428f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_audience_view.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupAudienceView",}, +) + + +class AdGroupAudienceView(proto.Message): + r"""An ad group audience view. + Includes performance data from interests and remarketing lists + for Display Network and YouTube Network ads, and remarketing + lists for search ads (RLSA), aggregated at the audience level. + + Attributes: + resource_name (str): + Output only. The resource name of the ad group audience + view. Ad group audience view resource names have the form: + + ``customers/{customer_id}/adGroupAudienceViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_bid_modifier.py b/google/ads/googleads/v12/resources/types/ad_group_bid_modifier.py new file mode 100644 index 000000000..dfeced676 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_bid_modifier.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import ( + bid_modifier_source as gage_bid_modifier_source, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupBidModifier",}, +) + + +class AdGroupBidModifier(proto.Message): + r"""Represents an ad group bid modifier. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group bid modifier. + Ad group bid modifier resource names have the form: + + ``customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}`` + ad_group (str): + Immutable. The ad group to which this + criterion belongs. + + This field is a member of `oneof`_ ``_ad_group``. + criterion_id (int): + Output only. The ID of the criterion to bid + modify. + This field is ignored for mutates. + + This field is a member of `oneof`_ ``_criterion_id``. + bid_modifier (float): + The modifier for the bid when the criterion + matches. The modifier must be in the range: 0.1 + - 10.0. The range is 1.0 - 6.0 for + PreferredContent. Use 0 to opt out of a Device + type. + + This field is a member of `oneof`_ ``_bid_modifier``. + base_ad_group (str): + Output only. The base ad group from which this draft/trial + adgroup bid modifier was created. If ad_group is a base ad + group then this field will be equal to ad_group. If the ad + group was created in the draft or trial and has no + corresponding base ad group, then this field will be null. + This field is readonly. + + This field is a member of `oneof`_ ``_base_ad_group``. + bid_modifier_source (google.ads.googleads.v12.enums.types.BidModifierSourceEnum.BidModifierSource): + Output only. Bid modifier source. + hotel_date_selection_type (google.ads.googleads.v12.common.types.HotelDateSelectionTypeInfo): + Immutable. Criterion for hotel date selection + (default dates versus user selected). + + This field is a member of `oneof`_ ``criterion``. + hotel_advance_booking_window (google.ads.googleads.v12.common.types.HotelAdvanceBookingWindowInfo): + Immutable. Criterion for number of days prior + to the stay the booking is being made. + + This field is a member of `oneof`_ ``criterion``. + hotel_length_of_stay (google.ads.googleads.v12.common.types.HotelLengthOfStayInfo): + Immutable. Criterion for length of hotel stay + in nights. + + This field is a member of `oneof`_ ``criterion``. + hotel_check_in_day (google.ads.googleads.v12.common.types.HotelCheckInDayInfo): + Immutable. Criterion for day of the week the + booking is for. + + This field is a member of `oneof`_ ``criterion``. + device (google.ads.googleads.v12.common.types.DeviceInfo): + Immutable. A device criterion. + + This field is a member of `oneof`_ ``criterion``. + preferred_content (google.ads.googleads.v12.common.types.PreferredContentInfo): + Immutable. A preferred content criterion. + + This field is a member of `oneof`_ ``criterion``. + hotel_check_in_date_range (google.ads.googleads.v12.common.types.HotelCheckInDateRangeInfo): + Immutable. Criterion for a hotel check-in + date range. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field(proto.STRING, number=13, optional=True,) + criterion_id = proto.Field(proto.INT64, number=14, optional=True,) + bid_modifier = proto.Field(proto.DOUBLE, number=15, optional=True,) + base_ad_group = proto.Field(proto.STRING, number=16, optional=True,) + bid_modifier_source = proto.Field( + proto.ENUM, + number=10, + enum=gage_bid_modifier_source.BidModifierSourceEnum.BidModifierSource, + ) + hotel_date_selection_type = proto.Field( + proto.MESSAGE, + number=5, + oneof="criterion", + message=criteria.HotelDateSelectionTypeInfo, + ) + hotel_advance_booking_window = proto.Field( + proto.MESSAGE, + number=6, + oneof="criterion", + message=criteria.HotelAdvanceBookingWindowInfo, + ) + hotel_length_of_stay = proto.Field( + proto.MESSAGE, + number=7, + oneof="criterion", + message=criteria.HotelLengthOfStayInfo, + ) + hotel_check_in_day = proto.Field( + proto.MESSAGE, + number=8, + oneof="criterion", + message=criteria.HotelCheckInDayInfo, + ) + device = proto.Field( + proto.MESSAGE, + number=11, + oneof="criterion", + message=criteria.DeviceInfo, + ) + preferred_content = proto.Field( + proto.MESSAGE, + number=12, + oneof="criterion", + message=criteria.PreferredContentInfo, + ) + hotel_check_in_date_range = proto.Field( + proto.MESSAGE, + number=17, + oneof="criterion", + message=criteria.HotelCheckInDateRangeInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_criterion.py b/google/ads/googleads/v12/resources/types/ad_group_criterion.py new file mode 100644 index 000000000..a163592cb --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_criterion.py @@ -0,0 +1,566 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.enums.types import ( + ad_group_criterion_approval_status, +) +from google.ads.googleads.v12.enums.types import ad_group_criterion_status +from google.ads.googleads.v12.enums.types import bidding_source +from google.ads.googleads.v12.enums.types import criterion_system_serving_status +from google.ads.googleads.v12.enums.types import criterion_type +from google.ads.googleads.v12.enums.types import quality_score_bucket + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterion",}, +) + + +class AdGroupCriterion(proto.Message): + r"""An ad group criterion. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group criterion. Ad + group criterion resource names have the form: + + ``customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}`` + criterion_id (int): + Output only. The ID of the criterion. + This field is ignored for mutates. + + This field is a member of `oneof`_ ``_criterion_id``. + display_name (str): + Output only. The display name of the + criterion. + This field is ignored for mutates. + status (google.ads.googleads.v12.enums.types.AdGroupCriterionStatusEnum.AdGroupCriterionStatus): + The status of the criterion. + This is the status of the ad group criterion + entity, set by the client. Note: UI reports may + incorporate additional information that affects + whether a criterion is eligible to run. In some + cases a criterion that's REMOVED in the API can + still show as enabled in the UI. For example, + campaigns by default show to users of all age + ranges unless excluded. The UI will show each + age range as "enabled", since they're eligible + to see the ads; but AdGroupCriterion.status will + show "removed", since no positive criterion was + added. + quality_info (google.ads.googleads.v12.resources.types.AdGroupCriterion.QualityInfo): + Output only. Information regarding the + quality of the criterion. + ad_group (str): + Immutable. The ad group to which the + criterion belongs. + + This field is a member of `oneof`_ ``_ad_group``. + type_ (google.ads.googleads.v12.enums.types.CriterionTypeEnum.CriterionType): + Output only. The type of the criterion. + negative (bool): + Immutable. Whether to target (``false``) or exclude + (``true``) the criterion. + + This field is immutable. To switch a criterion from positive + to negative, remove then re-add it. + + This field is a member of `oneof`_ ``_negative``. + system_serving_status (google.ads.googleads.v12.enums.types.CriterionSystemServingStatusEnum.CriterionSystemServingStatus): + Output only. Serving status of the criterion. + approval_status (google.ads.googleads.v12.enums.types.AdGroupCriterionApprovalStatusEnum.AdGroupCriterionApprovalStatus): + Output only. Approval status of the + criterion. + disapproval_reasons (Sequence[str]): + Output only. List of disapproval reasons of + the criterion. + The different reasons for disapproving a + criterion can be found here: + https://support.google.com/adspolicy/answer/6008942 + This field is read-only. + labels (Sequence[str]): + Output only. The resource names of labels + attached to this ad group criterion. + bid_modifier (float): + The modifier for the bid when the criterion + matches. The modifier must be in the range: 0.1 + - 10.0. Most targetable criteria types support + modifiers. + + This field is a member of `oneof`_ ``_bid_modifier``. + cpc_bid_micros (int): + The CPC (cost-per-click) bid. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + cpm_bid_micros (int): + The CPM (cost-per-thousand viewable + impressions) bid. + + This field is a member of `oneof`_ ``_cpm_bid_micros``. + cpv_bid_micros (int): + The CPV (cost-per-view) bid. + + This field is a member of `oneof`_ ``_cpv_bid_micros``. + percent_cpc_bid_micros (int): + The CPC bid amount, expressed as a fraction of the + advertised price for some good or service. The valid range + for the fraction is [0,1) and the value stored here is + 1,000,000 \* [fraction]. + + This field is a member of `oneof`_ ``_percent_cpc_bid_micros``. + effective_cpc_bid_micros (int): + Output only. The effective CPC + (cost-per-click) bid. + + This field is a member of `oneof`_ ``_effective_cpc_bid_micros``. + effective_cpm_bid_micros (int): + Output only. The effective CPM + (cost-per-thousand viewable impressions) bid. + + This field is a member of `oneof`_ ``_effective_cpm_bid_micros``. + effective_cpv_bid_micros (int): + Output only. The effective CPV + (cost-per-view) bid. + + This field is a member of `oneof`_ ``_effective_cpv_bid_micros``. + effective_percent_cpc_bid_micros (int): + Output only. The effective Percent CPC bid + amount. + + This field is a member of `oneof`_ ``_effective_percent_cpc_bid_micros``. + effective_cpc_bid_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective CPC bid. + effective_cpm_bid_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective CPM bid. + effective_cpv_bid_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective CPV bid. + effective_percent_cpc_bid_source (google.ads.googleads.v12.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective Percent + CPC bid. + position_estimates (google.ads.googleads.v12.resources.types.AdGroupCriterion.PositionEstimates): + Output only. Estimates for criterion bids at + various positions. + final_urls (Sequence[str]): + The list of possible final URLs after all + cross-domain redirects for the ad. + final_mobile_urls (Sequence[str]): + The list of possible final mobile URLs after + all cross-domain redirects. + final_url_suffix (str): + URL template for appending params to final + URL. + + This field is a member of `oneof`_ ``_final_url_suffix``. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Immutable. Keyword. + + This field is a member of `oneof`_ ``criterion``. + placement (google.ads.googleads.v12.common.types.PlacementInfo): + Immutable. Placement. + + This field is a member of `oneof`_ ``criterion``. + mobile_app_category (google.ads.googleads.v12.common.types.MobileAppCategoryInfo): + Immutable. Mobile app category. + + This field is a member of `oneof`_ ``criterion``. + mobile_application (google.ads.googleads.v12.common.types.MobileApplicationInfo): + Immutable. Mobile application. + + This field is a member of `oneof`_ ``criterion``. + listing_group (google.ads.googleads.v12.common.types.ListingGroupInfo): + Immutable. Listing group. + + This field is a member of `oneof`_ ``criterion``. + age_range (google.ads.googleads.v12.common.types.AgeRangeInfo): + Immutable. Age range. + + This field is a member of `oneof`_ ``criterion``. + gender (google.ads.googleads.v12.common.types.GenderInfo): + Immutable. Gender. + + This field is a member of `oneof`_ ``criterion``. + income_range (google.ads.googleads.v12.common.types.IncomeRangeInfo): + Immutable. Income range. + + This field is a member of `oneof`_ ``criterion``. + parental_status (google.ads.googleads.v12.common.types.ParentalStatusInfo): + Immutable. Parental status. + + This field is a member of `oneof`_ ``criterion``. + user_list (google.ads.googleads.v12.common.types.UserListInfo): + Immutable. User List. + + This field is a member of `oneof`_ ``criterion``. + youtube_video (google.ads.googleads.v12.common.types.YouTubeVideoInfo): + Immutable. YouTube Video. + + This field is a member of `oneof`_ ``criterion``. + youtube_channel (google.ads.googleads.v12.common.types.YouTubeChannelInfo): + Immutable. YouTube Channel. + + This field is a member of `oneof`_ ``criterion``. + topic (google.ads.googleads.v12.common.types.TopicInfo): + Immutable. Topic. + + This field is a member of `oneof`_ ``criterion``. + user_interest (google.ads.googleads.v12.common.types.UserInterestInfo): + Immutable. User Interest. + + This field is a member of `oneof`_ ``criterion``. + webpage (google.ads.googleads.v12.common.types.WebpageInfo): + Immutable. Webpage + + This field is a member of `oneof`_ ``criterion``. + app_payment_model (google.ads.googleads.v12.common.types.AppPaymentModelInfo): + Immutable. App Payment Model. + + This field is a member of `oneof`_ ``criterion``. + custom_affinity (google.ads.googleads.v12.common.types.CustomAffinityInfo): + Immutable. Custom Affinity. + + This field is a member of `oneof`_ ``criterion``. + custom_intent (google.ads.googleads.v12.common.types.CustomIntentInfo): + Immutable. Custom Intent. + + This field is a member of `oneof`_ ``criterion``. + custom_audience (google.ads.googleads.v12.common.types.CustomAudienceInfo): + Immutable. Custom Audience. + + This field is a member of `oneof`_ ``criterion``. + combined_audience (google.ads.googleads.v12.common.types.CombinedAudienceInfo): + Immutable. Combined Audience. + + This field is a member of `oneof`_ ``criterion``. + audience (google.ads.googleads.v12.common.types.AudienceInfo): + Immutable. Audience. + + This field is a member of `oneof`_ ``criterion``. + """ + + class QualityInfo(proto.Message): + r"""A container for ad group criterion quality information. + + Attributes: + quality_score (int): + Output only. The quality score. + This field may not be populated if Google does + not have enough information to determine a + value. + + This field is a member of `oneof`_ ``_quality_score``. + creative_quality_score (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + Output only. The performance of the ad + compared to other advertisers. + post_click_quality_score (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + Output only. The quality score of the landing + page. + search_predicted_ctr (google.ads.googleads.v12.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + Output only. The click-through rate compared + to that of other advertisers. + """ + + quality_score = proto.Field(proto.INT32, number=5, optional=True,) + creative_quality_score = proto.Field( + proto.ENUM, + number=2, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + post_click_quality_score = proto.Field( + proto.ENUM, + number=3, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + search_predicted_ctr = proto.Field( + proto.ENUM, + number=4, + enum=quality_score_bucket.QualityScoreBucketEnum.QualityScoreBucket, + ) + + class PositionEstimates(proto.Message): + r"""Estimates for criterion bids at various positions. + + Attributes: + first_page_cpc_micros (int): + Output only. The estimate of the CPC bid + required for ad to be shown on first page of + search results. + + This field is a member of `oneof`_ ``_first_page_cpc_micros``. + first_position_cpc_micros (int): + Output only. The estimate of the CPC bid + required for ad to be displayed in first + position, at the top of the first page of search + results. + + This field is a member of `oneof`_ ``_first_position_cpc_micros``. + top_of_page_cpc_micros (int): + Output only. The estimate of the CPC bid + required for ad to be displayed at the top of + the first page of search results. + + This field is a member of `oneof`_ ``_top_of_page_cpc_micros``. + estimated_add_clicks_at_first_position_cpc (int): + Output only. Estimate of how many clicks per week you might + get by changing your keyword bid to the value in + first_position_cpc_micros. + + This field is a member of `oneof`_ ``_estimated_add_clicks_at_first_position_cpc``. + estimated_add_cost_at_first_position_cpc (int): + Output only. Estimate of how your cost per week might change + when changing your keyword bid to the value in + first_position_cpc_micros. + + This field is a member of `oneof`_ ``_estimated_add_cost_at_first_position_cpc``. + """ + + first_page_cpc_micros = proto.Field( + proto.INT64, number=6, optional=True, + ) + first_position_cpc_micros = proto.Field( + proto.INT64, number=7, optional=True, + ) + top_of_page_cpc_micros = proto.Field( + proto.INT64, number=8, optional=True, + ) + estimated_add_clicks_at_first_position_cpc = proto.Field( + proto.INT64, number=9, optional=True, + ) + estimated_add_cost_at_first_position_cpc = proto.Field( + proto.INT64, number=10, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + criterion_id = proto.Field(proto.INT64, number=56, optional=True,) + display_name = proto.Field(proto.STRING, number=77,) + status = proto.Field( + proto.ENUM, + number=3, + enum=ad_group_criterion_status.AdGroupCriterionStatusEnum.AdGroupCriterionStatus, + ) + quality_info = proto.Field(proto.MESSAGE, number=4, message=QualityInfo,) + ad_group = proto.Field(proto.STRING, number=57, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=25, + enum=criterion_type.CriterionTypeEnum.CriterionType, + ) + negative = proto.Field(proto.BOOL, number=58, optional=True,) + system_serving_status = proto.Field( + proto.ENUM, + number=52, + enum=criterion_system_serving_status.CriterionSystemServingStatusEnum.CriterionSystemServingStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=53, + enum=ad_group_criterion_approval_status.AdGroupCriterionApprovalStatusEnum.AdGroupCriterionApprovalStatus, + ) + disapproval_reasons = proto.RepeatedField(proto.STRING, number=59,) + labels = proto.RepeatedField(proto.STRING, number=60,) + bid_modifier = proto.Field(proto.DOUBLE, number=61, optional=True,) + cpc_bid_micros = proto.Field(proto.INT64, number=62, optional=True,) + cpm_bid_micros = proto.Field(proto.INT64, number=63, optional=True,) + cpv_bid_micros = proto.Field(proto.INT64, number=64, optional=True,) + percent_cpc_bid_micros = proto.Field(proto.INT64, number=65, optional=True,) + effective_cpc_bid_micros = proto.Field( + proto.INT64, number=66, optional=True, + ) + effective_cpm_bid_micros = proto.Field( + proto.INT64, number=67, optional=True, + ) + effective_cpv_bid_micros = proto.Field( + proto.INT64, number=68, optional=True, + ) + effective_percent_cpc_bid_micros = proto.Field( + proto.INT64, number=69, optional=True, + ) + effective_cpc_bid_source = proto.Field( + proto.ENUM, + number=21, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_cpm_bid_source = proto.Field( + proto.ENUM, + number=22, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_cpv_bid_source = proto.Field( + proto.ENUM, + number=23, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_percent_cpc_bid_source = proto.Field( + proto.ENUM, + number=35, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + position_estimates = proto.Field( + proto.MESSAGE, number=10, message=PositionEstimates, + ) + final_urls = proto.RepeatedField(proto.STRING, number=70,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=71,) + final_url_suffix = proto.Field(proto.STRING, number=72, optional=True,) + tracking_url_template = proto.Field(proto.STRING, number=73, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=14, message=custom_parameter.CustomParameter, + ) + keyword = proto.Field( + proto.MESSAGE, + number=27, + oneof="criterion", + message=criteria.KeywordInfo, + ) + placement = proto.Field( + proto.MESSAGE, + number=28, + oneof="criterion", + message=criteria.PlacementInfo, + ) + mobile_app_category = proto.Field( + proto.MESSAGE, + number=29, + oneof="criterion", + message=criteria.MobileAppCategoryInfo, + ) + mobile_application = proto.Field( + proto.MESSAGE, + number=30, + oneof="criterion", + message=criteria.MobileApplicationInfo, + ) + listing_group = proto.Field( + proto.MESSAGE, + number=32, + oneof="criterion", + message=criteria.ListingGroupInfo, + ) + age_range = proto.Field( + proto.MESSAGE, + number=36, + oneof="criterion", + message=criteria.AgeRangeInfo, + ) + gender = proto.Field( + proto.MESSAGE, + number=37, + oneof="criterion", + message=criteria.GenderInfo, + ) + income_range = proto.Field( + proto.MESSAGE, + number=38, + oneof="criterion", + message=criteria.IncomeRangeInfo, + ) + parental_status = proto.Field( + proto.MESSAGE, + number=39, + oneof="criterion", + message=criteria.ParentalStatusInfo, + ) + user_list = proto.Field( + proto.MESSAGE, + number=42, + oneof="criterion", + message=criteria.UserListInfo, + ) + youtube_video = proto.Field( + proto.MESSAGE, + number=40, + oneof="criterion", + message=criteria.YouTubeVideoInfo, + ) + youtube_channel = proto.Field( + proto.MESSAGE, + number=41, + oneof="criterion", + message=criteria.YouTubeChannelInfo, + ) + topic = proto.Field( + proto.MESSAGE, number=43, oneof="criterion", message=criteria.TopicInfo, + ) + user_interest = proto.Field( + proto.MESSAGE, + number=45, + oneof="criterion", + message=criteria.UserInterestInfo, + ) + webpage = proto.Field( + proto.MESSAGE, + number=46, + oneof="criterion", + message=criteria.WebpageInfo, + ) + app_payment_model = proto.Field( + proto.MESSAGE, + number=47, + oneof="criterion", + message=criteria.AppPaymentModelInfo, + ) + custom_affinity = proto.Field( + proto.MESSAGE, + number=48, + oneof="criterion", + message=criteria.CustomAffinityInfo, + ) + custom_intent = proto.Field( + proto.MESSAGE, + number=49, + oneof="criterion", + message=criteria.CustomIntentInfo, + ) + custom_audience = proto.Field( + proto.MESSAGE, + number=74, + oneof="criterion", + message=criteria.CustomAudienceInfo, + ) + combined_audience = proto.Field( + proto.MESSAGE, + number=75, + oneof="criterion", + message=criteria.CombinedAudienceInfo, + ) + audience = proto.Field( + proto.MESSAGE, + number=79, + oneof="criterion", + message=criteria.AudienceInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_criterion_customizer.py b/google/ads/googleads/v12/resources/types/ad_group_criterion_customizer.py new file mode 100644 index 000000000..d9340ca3d --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_criterion_customizer.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import customizer_value +from google.ads.googleads.v12.enums.types import customizer_value_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionCustomizer",}, +) + + +class AdGroupCriterionCustomizer(proto.Message): + r"""A customizer value for the associated CustomizerAttribute at + the AdGroupCriterion level. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group criterion + customizer. Ad group criterion customizer resource names + have the form: + + ``customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}`` + ad_group_criterion (str): + Immutable. The ad group criterion to which + the customizer attribute is linked. It must be a + keyword criterion. + + This field is a member of `oneof`_ ``_ad_group_criterion``. + customizer_attribute (str): + Required. Immutable. The customizer attribute + which is linked to the ad group criterion. + status (google.ads.googleads.v12.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + Output only. The status of the ad group + criterion customizer. + value (google.ads.googleads.v12.common.types.CustomizerValue): + Required. The value to associate with the + customizer attribute at this level. The value + must be of the type specified for the + CustomizerAttribute. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_criterion = proto.Field(proto.STRING, number=2, optional=True,) + customizer_attribute = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=customizer_value_status.CustomizerValueStatusEnum.CustomizerValueStatus, + ) + value = proto.Field( + proto.MESSAGE, number=5, message=customizer_value.CustomizerValue, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_criterion_label.py b/google/ads/googleads/v12/resources/types/ad_group_criterion_label.py new file mode 100644 index 000000000..e9c81ac53 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_criterion_label.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionLabel",}, +) + + +class AdGroupCriterionLabel(proto.Message): + r"""A relationship between an ad group criterion and a label. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group criterion + label. Ad group criterion label resource names have the + form: + ``customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}`` + ad_group_criterion (str): + Immutable. The ad group criterion to which + the label is attached. + + This field is a member of `oneof`_ ``_ad_group_criterion``. + label (str): + Immutable. The label assigned to the ad group + criterion. + + This field is a member of `oneof`_ ``_label``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_criterion = proto.Field(proto.STRING, number=4, optional=True,) + label = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_criterion_simulation.py b/google/ads/googleads/v12/resources/types/ad_group_criterion_simulation.py new file mode 100644 index 000000000..8e8e0dd1b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_criterion_simulation.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import simulation +from google.ads.googleads.v12.enums.types import simulation_modification_method +from google.ads.googleads.v12.enums.types import simulation_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCriterionSimulation",}, +) + + +class AdGroupCriterionSimulation(proto.Message): + r"""An ad group criterion simulation. Supported combinations of + advertising channel type, criterion type, simulation type, and + simulation modification method are detailed below respectively. + Hotel AdGroupCriterion simulation operations starting in V5. + + 1. DISPLAY - KEYWORD - CPC_BID - UNIFORM + 2. SEARCH - KEYWORD - CPC_BID - UNIFORM + 3. SHOPPING - LISTING_GROUP - CPC_BID - UNIFORM + 4. HOTEL - LISTING_GROUP - CPC_BID - UNIFORM + 5. HOTEL - LISTING_GROUP - PERCENT_CPC_BID - UNIFORM + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the ad group criterion + simulation. Ad group criterion simulation resource names + have the form: + + ``customers/{customer_id}/adGroupCriterionSimulations/{ad_group_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}`` + ad_group_id (int): + Output only. AdGroup ID of the simulation. + + This field is a member of `oneof`_ ``_ad_group_id``. + criterion_id (int): + Output only. Criterion ID of the simulation. + + This field is a member of `oneof`_ ``_criterion_id``. + type_ (google.ads.googleads.v12.enums.types.SimulationTypeEnum.SimulationType): + Output only. The field that the simulation + modifies. + modification_method (google.ads.googleads.v12.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + Output only. How the simulation modifies the + field. + start_date (str): + Output only. First day on which the + simulation is based, in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_start_date``. + end_date (str): + Output only. Last day on which the simulation + is based, in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_end_date``. + cpc_bid_point_list (google.ads.googleads.v12.common.types.CpcBidSimulationPointList): + Output only. Simulation points if the simulation type is + CPC_BID. + + This field is a member of `oneof`_ ``point_list``. + percent_cpc_bid_point_list (google.ads.googleads.v12.common.types.PercentCpcBidSimulationPointList): + Output only. Simulation points if the simulation type is + PERCENT_CPC_BID. + + This field is a member of `oneof`_ ``point_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_id = proto.Field(proto.INT64, number=9, optional=True,) + criterion_id = proto.Field(proto.INT64, number=10, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=simulation_type.SimulationTypeEnum.SimulationType, + ) + modification_method = proto.Field( + proto.ENUM, + number=5, + enum=simulation_modification_method.SimulationModificationMethodEnum.SimulationModificationMethod, + ) + start_date = proto.Field(proto.STRING, number=11, optional=True,) + end_date = proto.Field(proto.STRING, number=12, optional=True,) + cpc_bid_point_list = proto.Field( + proto.MESSAGE, + number=8, + oneof="point_list", + message=simulation.CpcBidSimulationPointList, + ) + percent_cpc_bid_point_list = proto.Field( + proto.MESSAGE, + number=13, + oneof="point_list", + message=simulation.PercentCpcBidSimulationPointList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_customizer.py b/google/ads/googleads/v12/resources/types/ad_group_customizer.py new file mode 100644 index 000000000..1a26ab1cc --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_customizer.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import customizer_value +from google.ads.googleads.v12.enums.types import customizer_value_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupCustomizer",}, +) + + +class AdGroupCustomizer(proto.Message): + r"""A customizer value for the associated CustomizerAttribute at + the AdGroup level. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group customizer. Ad + group customizer resource names have the form: + + ``customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}`` + ad_group (str): + Immutable. The ad group to which the + customizer attribute is linked. + customizer_attribute (str): + Required. Immutable. The customizer attribute + which is linked to the ad group. + status (google.ads.googleads.v12.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + Output only. The status of the ad group + customizer. + value (google.ads.googleads.v12.common.types.CustomizerValue): + Required. The value to associate with the + customizer attribute at this level. The value + must be of the type specified for the + CustomizerAttribute. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field(proto.STRING, number=2,) + customizer_attribute = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=customizer_value_status.CustomizerValueStatusEnum.CustomizerValueStatus, + ) + value = proto.Field( + proto.MESSAGE, number=5, message=customizer_value.CustomizerValue, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_extension_setting.py b/google/ads/googleads/v12/resources/types/ad_group_extension_setting.py new file mode 100644 index 000000000..b4b9e553c --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_extension_setting.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import extension_setting_device +from google.ads.googleads.v12.enums.types import ( + extension_type as gage_extension_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupExtensionSetting",}, +) + + +class AdGroupExtensionSetting(proto.Message): + r"""An ad group extension setting. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group extension + setting. AdGroupExtensionSetting resource names have the + form: + + ``customers/{customer_id}/adGroupExtensionSettings/{ad_group_id}~{extension_type}`` + extension_type (google.ads.googleads.v12.enums.types.ExtensionTypeEnum.ExtensionType): + Immutable. The extension type of the ad group + extension setting. + ad_group (str): + Immutable. The resource name of the ad group. The linked + extension feed items will serve under this ad group. AdGroup + resource names have the form: + + ``customers/{customer_id}/adGroups/{ad_group_id}`` + + This field is a member of `oneof`_ ``_ad_group``. + extension_feed_items (Sequence[str]): + The resource names of the extension feed items to serve + under the ad group. ExtensionFeedItem resource names have + the form: + + ``customers/{customer_id}/extensionFeedItems/{feed_item_id}`` + device (google.ads.googleads.v12.enums.types.ExtensionSettingDeviceEnum.ExtensionSettingDevice): + The device for which the extensions will + serve. Optional. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + extension_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_extension_type.ExtensionTypeEnum.ExtensionType, + ) + ad_group = proto.Field(proto.STRING, number=6, optional=True,) + extension_feed_items = proto.RepeatedField(proto.STRING, number=7,) + device = proto.Field( + proto.ENUM, + number=5, + enum=extension_setting_device.ExtensionSettingDeviceEnum.ExtensionSettingDevice, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_feed.py b/google/ads/googleads/v12/resources/types/ad_group_feed.py new file mode 100644 index 000000000..9d45d0367 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_feed.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + matching_function as gagc_matching_function, +) +from google.ads.googleads.v12.enums.types import feed_link_status +from google.ads.googleads.v12.enums.types import placeholder_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupFeed",}, +) + + +class AdGroupFeed(proto.Message): + r"""An ad group feed. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group feed. Ad group + feed resource names have the form: + + \`customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id} + feed (str): + Immutable. The feed being linked to the ad + group. + + This field is a member of `oneof`_ ``_feed``. + ad_group (str): + Immutable. The ad group being linked to the + feed. + + This field is a member of `oneof`_ ``_ad_group``. + placeholder_types (Sequence[google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType]): + Indicates which placeholder types the feed + may populate under the connected ad group. + Required. + matching_function (google.ads.googleads.v12.common.types.MatchingFunction): + Matching function associated with the + AdGroupFeed. The matching function is used to + filter the set of feed items selected. Required. + status (google.ads.googleads.v12.enums.types.FeedLinkStatusEnum.FeedLinkStatus): + Output only. Status of the ad group feed. + This field is read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=7, optional=True,) + ad_group = proto.Field(proto.STRING, number=8, optional=True,) + placeholder_types = proto.RepeatedField( + proto.ENUM, + number=4, + enum=placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + matching_function = proto.Field( + proto.MESSAGE, + number=5, + message=gagc_matching_function.MatchingFunction, + ) + status = proto.Field( + proto.ENUM, + number=6, + enum=feed_link_status.FeedLinkStatusEnum.FeedLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_label.py b/google/ads/googleads/v12/resources/types/ad_group_label.py new file mode 100644 index 000000000..b2dce889f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_label.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupLabel",}, +) + + +class AdGroupLabel(proto.Message): + r"""A relationship between an ad group and a label. + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group label. Ad group + label resource names have the form: + ``customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}`` + ad_group (str): + Immutable. The ad group to which the label is + attached. + + This field is a member of `oneof`_ ``_ad_group``. + label (str): + Immutable. The label assigned to the ad + group. + + This field is a member of `oneof`_ ``_label``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field(proto.STRING, number=4, optional=True,) + label = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_group_simulation.py b/google/ads/googleads/v12/resources/types/ad_group_simulation.py new file mode 100644 index 000000000..6d835dc59 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_group_simulation.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import simulation +from google.ads.googleads.v12.enums.types import simulation_modification_method +from google.ads.googleads.v12.enums.types import simulation_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdGroupSimulation",}, +) + + +class AdGroupSimulation(proto.Message): + r"""An ad group simulation. Supported combinations of advertising + channel type, simulation type and simulation modification method is + detailed below respectively. + + 1. SEARCH - CPC_BID - DEFAULT + 2. SEARCH - CPC_BID - UNIFORM + 3. SEARCH - TARGET_CPA - UNIFORM + 4. SEARCH - TARGET_ROAS - UNIFORM + 5. DISPLAY - CPC_BID - DEFAULT + 6. DISPLAY - CPC_BID - UNIFORM + 7. DISPLAY - TARGET_CPA - UNIFORM + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the ad group simulation. + Ad group simulation resource names have the form: + + ``customers/{customer_id}/adGroupSimulations/{ad_group_id}~{type}~{modification_method}~{start_date}~{end_date}`` + ad_group_id (int): + Output only. Ad group id of the simulation. + + This field is a member of `oneof`_ ``_ad_group_id``. + type_ (google.ads.googleads.v12.enums.types.SimulationTypeEnum.SimulationType): + Output only. The field that the simulation + modifies. + modification_method (google.ads.googleads.v12.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + Output only. How the simulation modifies the + field. + start_date (str): + Output only. First day on which the + simulation is based, in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_start_date``. + end_date (str): + Output only. Last day on which the simulation + is based, in YYYY-MM-DD format + + This field is a member of `oneof`_ ``_end_date``. + cpc_bid_point_list (google.ads.googleads.v12.common.types.CpcBidSimulationPointList): + Output only. Simulation points if the simulation type is + CPC_BID. + + This field is a member of `oneof`_ ``point_list``. + cpv_bid_point_list (google.ads.googleads.v12.common.types.CpvBidSimulationPointList): + Output only. Simulation points if the simulation type is + CPV_BID. + + This field is a member of `oneof`_ ``point_list``. + target_cpa_point_list (google.ads.googleads.v12.common.types.TargetCpaSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_CPA. + + This field is a member of `oneof`_ ``point_list``. + target_roas_point_list (google.ads.googleads.v12.common.types.TargetRoasSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_ROAS. + + This field is a member of `oneof`_ ``point_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_id = proto.Field(proto.INT64, number=12, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=simulation_type.SimulationTypeEnum.SimulationType, + ) + modification_method = proto.Field( + proto.ENUM, + number=4, + enum=simulation_modification_method.SimulationModificationMethodEnum.SimulationModificationMethod, + ) + start_date = proto.Field(proto.STRING, number=13, optional=True,) + end_date = proto.Field(proto.STRING, number=14, optional=True,) + cpc_bid_point_list = proto.Field( + proto.MESSAGE, + number=8, + oneof="point_list", + message=simulation.CpcBidSimulationPointList, + ) + cpv_bid_point_list = proto.Field( + proto.MESSAGE, + number=10, + oneof="point_list", + message=simulation.CpvBidSimulationPointList, + ) + target_cpa_point_list = proto.Field( + proto.MESSAGE, + number=9, + oneof="point_list", + message=simulation.TargetCpaSimulationPointList, + ) + target_roas_point_list = proto.Field( + proto.MESSAGE, + number=11, + oneof="point_list", + message=simulation.TargetRoasSimulationPointList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_parameter.py b/google/ads/googleads/v12/resources/types/ad_parameter.py new file mode 100644 index 000000000..e6d499f50 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_parameter.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdParameter",}, +) + + +class AdParameter(proto.Message): + r"""An ad parameter that is used to update numeric values (such as + prices or inventory levels) in any text line of an ad (including + URLs). There can be a maximum of two AdParameters per ad group + criterion. (One with parameter_index = 1 and one with + parameter_index = 2.) In the ad the parameters are referenced by a + placeholder of the form "{param#:value}". For example, + "{param1:$17}" + + Attributes: + resource_name (str): + Immutable. The resource name of the ad parameter. Ad + parameter resource names have the form: + + ``customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}`` + ad_group_criterion (str): + Immutable. The ad group criterion that this + ad parameter belongs to. + + This field is a member of `oneof`_ ``_ad_group_criterion``. + parameter_index (int): + Immutable. The unique index of this ad + parameter. Must be either 1 or 2. + + This field is a member of `oneof`_ ``_parameter_index``. + insertion_text (str): + Numeric value to insert into the ad text. The + following restrictions apply: + - Can use comma or period as a separator, with + an optional period or comma (respectively) + for fractional values. For example, 1,000,000.00 + and 2.000.000,10 are valid. + - Can be prepended or appended with a currency + symbol. For example, $99.99 is valid. + - Can be prepended or appended with a currency + code. For example, 99.99USD and EUR200 are + valid. + - Can use '%'. For example, 1.0% and 1,0% are + valid. - Can use plus or minus. For example, + -10.99 and 25+ are valid. - Can use '/' between + two numbers. For example 4/1 and 0.95/0.45 are + valid. + + This field is a member of `oneof`_ ``_insertion_text``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_criterion = proto.Field(proto.STRING, number=5, optional=True,) + parameter_index = proto.Field(proto.INT64, number=6, optional=True,) + insertion_text = proto.Field(proto.STRING, number=7, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/ad_schedule_view.py b/google/ads/googleads/v12/resources/types/ad_schedule_view.py new file mode 100644 index 000000000..3d5bd07f8 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/ad_schedule_view.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AdScheduleView",}, +) + + +class AdScheduleView(proto.Message): + r"""An ad schedule view summarizes the performance of campaigns + by AdSchedule criteria. + + Attributes: + resource_name (str): + Output only. The resource name of the ad schedule view. + AdSchedule view resource names have the form: + + ``customers/{customer_id}/adScheduleViews/{campaign_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/age_range_view.py b/google/ads/googleads/v12/resources/types/age_range_view.py new file mode 100644 index 000000000..e512a9ae1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/age_range_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AgeRangeView",}, +) + + +class AgeRangeView(proto.Message): + r"""An age range view. + + Attributes: + resource_name (str): + Output only. The resource name of the age range view. Age + range view resource names have the form: + + ``customers/{customer_id}/ageRangeViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset.py b/google/ads/googleads/v12/resources/types/asset.py new file mode 100644 index 000000000..1c59b2382 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset.py @@ -0,0 +1,402 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import asset_types +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import asset_source +from google.ads.googleads.v12.enums.types import asset_type +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Asset", "AssetPolicySummary",}, +) + + +class Asset(proto.Message): + r"""Asset is a part of an ad which can be shared across multiple + ads. It can be an image (ImageAsset), a video + (YoutubeVideoAsset), etc. Assets are immutable and cannot be + removed. To stop an asset from serving, remove the asset from + the entity that is using it. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the asset. Asset resource + names have the form: + + ``customers/{customer_id}/assets/{asset_id}`` + id (int): + Output only. The ID of the asset. + + This field is a member of `oneof`_ ``_id``. + name (str): + Optional name of the asset. + + This field is a member of `oneof`_ ``_name``. + type_ (google.ads.googleads.v12.enums.types.AssetTypeEnum.AssetType): + Output only. Type of the asset. + final_urls (Sequence[str]): + A list of possible final URLs after all cross + domain redirects. + final_mobile_urls (Sequence[str]): + A list of possible final mobile URLs after + all cross domain redirects. + tracking_url_template (str): + URL template for constructing a tracking URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + A list of mappings to be used for substituting URL custom + parameter tags in the tracking_url_template, final_urls, + and/or final_mobile_urls. + final_url_suffix (str): + URL template for appending params to landing + page URLs served with parallel tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + source (google.ads.googleads.v12.enums.types.AssetSourceEnum.AssetSource): + Output only. Source of the asset. + policy_summary (google.ads.googleads.v12.resources.types.AssetPolicySummary): + Output only. Policy information for the + asset. + youtube_video_asset (google.ads.googleads.v12.common.types.YoutubeVideoAsset): + Immutable. A YouTube video asset. + + This field is a member of `oneof`_ ``asset_data``. + media_bundle_asset (google.ads.googleads.v12.common.types.MediaBundleAsset): + Immutable. A media bundle asset. + + This field is a member of `oneof`_ ``asset_data``. + image_asset (google.ads.googleads.v12.common.types.ImageAsset): + Output only. An image asset. + + This field is a member of `oneof`_ ``asset_data``. + text_asset (google.ads.googleads.v12.common.types.TextAsset): + Immutable. A text asset. + + This field is a member of `oneof`_ ``asset_data``. + lead_form_asset (google.ads.googleads.v12.common.types.LeadFormAsset): + A lead form asset. + + This field is a member of `oneof`_ ``asset_data``. + book_on_google_asset (google.ads.googleads.v12.common.types.BookOnGoogleAsset): + A book on google asset. + + This field is a member of `oneof`_ ``asset_data``. + promotion_asset (google.ads.googleads.v12.common.types.PromotionAsset): + A promotion asset. + + This field is a member of `oneof`_ ``asset_data``. + callout_asset (google.ads.googleads.v12.common.types.CalloutAsset): + A callout asset. + + This field is a member of `oneof`_ ``asset_data``. + structured_snippet_asset (google.ads.googleads.v12.common.types.StructuredSnippetAsset): + A structured snippet asset. + + This field is a member of `oneof`_ ``asset_data``. + sitelink_asset (google.ads.googleads.v12.common.types.SitelinkAsset): + A sitelink asset. + + This field is a member of `oneof`_ ``asset_data``. + page_feed_asset (google.ads.googleads.v12.common.types.PageFeedAsset): + A page feed asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_education_asset (google.ads.googleads.v12.common.types.DynamicEducationAsset): + A dynamic education asset. + + This field is a member of `oneof`_ ``asset_data``. + mobile_app_asset (google.ads.googleads.v12.common.types.MobileAppAsset): + A mobile app asset. + + This field is a member of `oneof`_ ``asset_data``. + hotel_callout_asset (google.ads.googleads.v12.common.types.HotelCalloutAsset): + A hotel callout asset. + + This field is a member of `oneof`_ ``asset_data``. + call_asset (google.ads.googleads.v12.common.types.CallAsset): + A call asset. + + This field is a member of `oneof`_ ``asset_data``. + price_asset (google.ads.googleads.v12.common.types.PriceAsset): + A price asset. + + This field is a member of `oneof`_ ``asset_data``. + call_to_action_asset (google.ads.googleads.v12.common.types.CallToActionAsset): + Immutable. A call to action asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_real_estate_asset (google.ads.googleads.v12.common.types.DynamicRealEstateAsset): + A dynamic real estate asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_custom_asset (google.ads.googleads.v12.common.types.DynamicCustomAsset): + A dynamic custom asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_hotels_and_rentals_asset (google.ads.googleads.v12.common.types.DynamicHotelsAndRentalsAsset): + A dynamic hotels and rentals asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_flights_asset (google.ads.googleads.v12.common.types.DynamicFlightsAsset): + A dynamic flights asset. + + This field is a member of `oneof`_ ``asset_data``. + discovery_carousel_card_asset (google.ads.googleads.v12.common.types.DiscoveryCarouselCardAsset): + Immutable. A discovery carousel card asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_travel_asset (google.ads.googleads.v12.common.types.DynamicTravelAsset): + A dynamic travel asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_local_asset (google.ads.googleads.v12.common.types.DynamicLocalAsset): + A dynamic local asset. + + This field is a member of `oneof`_ ``asset_data``. + dynamic_jobs_asset (google.ads.googleads.v12.common.types.DynamicJobsAsset): + A dynamic jobs asset. + + This field is a member of `oneof`_ ``asset_data``. + location_asset (google.ads.googleads.v12.common.types.LocationAsset): + Output only. A location asset. + + This field is a member of `oneof`_ ``asset_data``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=11, optional=True,) + name = proto.Field(proto.STRING, number=12, optional=True,) + type_ = proto.Field( + proto.ENUM, number=4, enum=asset_type.AssetTypeEnum.AssetType, + ) + final_urls = proto.RepeatedField(proto.STRING, number=14,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=16,) + tracking_url_template = proto.Field(proto.STRING, number=17, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=18, message=custom_parameter.CustomParameter, + ) + final_url_suffix = proto.Field(proto.STRING, number=19, optional=True,) + source = proto.Field( + proto.ENUM, number=38, enum=asset_source.AssetSourceEnum.AssetSource, + ) + policy_summary = proto.Field( + proto.MESSAGE, number=13, message="AssetPolicySummary", + ) + youtube_video_asset = proto.Field( + proto.MESSAGE, + number=5, + oneof="asset_data", + message=asset_types.YoutubeVideoAsset, + ) + media_bundle_asset = proto.Field( + proto.MESSAGE, + number=6, + oneof="asset_data", + message=asset_types.MediaBundleAsset, + ) + image_asset = proto.Field( + proto.MESSAGE, + number=7, + oneof="asset_data", + message=asset_types.ImageAsset, + ) + text_asset = proto.Field( + proto.MESSAGE, + number=8, + oneof="asset_data", + message=asset_types.TextAsset, + ) + lead_form_asset = proto.Field( + proto.MESSAGE, + number=9, + oneof="asset_data", + message=asset_types.LeadFormAsset, + ) + book_on_google_asset = proto.Field( + proto.MESSAGE, + number=10, + oneof="asset_data", + message=asset_types.BookOnGoogleAsset, + ) + promotion_asset = proto.Field( + proto.MESSAGE, + number=15, + oneof="asset_data", + message=asset_types.PromotionAsset, + ) + callout_asset = proto.Field( + proto.MESSAGE, + number=20, + oneof="asset_data", + message=asset_types.CalloutAsset, + ) + structured_snippet_asset = proto.Field( + proto.MESSAGE, + number=21, + oneof="asset_data", + message=asset_types.StructuredSnippetAsset, + ) + sitelink_asset = proto.Field( + proto.MESSAGE, + number=22, + oneof="asset_data", + message=asset_types.SitelinkAsset, + ) + page_feed_asset = proto.Field( + proto.MESSAGE, + number=23, + oneof="asset_data", + message=asset_types.PageFeedAsset, + ) + dynamic_education_asset = proto.Field( + proto.MESSAGE, + number=24, + oneof="asset_data", + message=asset_types.DynamicEducationAsset, + ) + mobile_app_asset = proto.Field( + proto.MESSAGE, + number=25, + oneof="asset_data", + message=asset_types.MobileAppAsset, + ) + hotel_callout_asset = proto.Field( + proto.MESSAGE, + number=26, + oneof="asset_data", + message=asset_types.HotelCalloutAsset, + ) + call_asset = proto.Field( + proto.MESSAGE, + number=27, + oneof="asset_data", + message=asset_types.CallAsset, + ) + price_asset = proto.Field( + proto.MESSAGE, + number=28, + oneof="asset_data", + message=asset_types.PriceAsset, + ) + call_to_action_asset = proto.Field( + proto.MESSAGE, + number=29, + oneof="asset_data", + message=asset_types.CallToActionAsset, + ) + dynamic_real_estate_asset = proto.Field( + proto.MESSAGE, + number=30, + oneof="asset_data", + message=asset_types.DynamicRealEstateAsset, + ) + dynamic_custom_asset = proto.Field( + proto.MESSAGE, + number=31, + oneof="asset_data", + message=asset_types.DynamicCustomAsset, + ) + dynamic_hotels_and_rentals_asset = proto.Field( + proto.MESSAGE, + number=32, + oneof="asset_data", + message=asset_types.DynamicHotelsAndRentalsAsset, + ) + dynamic_flights_asset = proto.Field( + proto.MESSAGE, + number=33, + oneof="asset_data", + message=asset_types.DynamicFlightsAsset, + ) + discovery_carousel_card_asset = proto.Field( + proto.MESSAGE, + number=34, + oneof="asset_data", + message=asset_types.DiscoveryCarouselCardAsset, + ) + dynamic_travel_asset = proto.Field( + proto.MESSAGE, + number=35, + oneof="asset_data", + message=asset_types.DynamicTravelAsset, + ) + dynamic_local_asset = proto.Field( + proto.MESSAGE, + number=36, + oneof="asset_data", + message=asset_types.DynamicLocalAsset, + ) + dynamic_jobs_asset = proto.Field( + proto.MESSAGE, + number=37, + oneof="asset_data", + message=asset_types.DynamicJobsAsset, + ) + location_asset = proto.Field( + proto.MESSAGE, + number=39, + oneof="asset_data", + message=asset_types.LocationAsset, + ) + + +class AssetPolicySummary(proto.Message): + r"""Contains policy information for an asset. + + Attributes: + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + Output only. The list of policy findings for + this asset. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Output only. Where in the review process this + asset is. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + Output only. The overall approval status of + this asset, calculated based on the status of + its individual policy topic entries. + """ + + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=1, message=policy.PolicyTopicEntry, + ) + review_status = proto.Field( + proto.ENUM, + number=2, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_field_type_view.py b/google/ads/googleads/v12/resources/types/asset_field_type_view.py new file mode 100644 index 000000000..cb07d56a1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_field_type_view.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_field_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetFieldTypeView",}, +) + + +class AssetFieldTypeView(proto.Message): + r"""An asset field type view. + This view reports non-overcounted metrics for each asset field + type when the asset is used as extension. + + Attributes: + resource_name (str): + Output only. The resource name of the asset field type view. + Asset field type view resource names have the form: + + ``customers/{customer_id}/assetFieldTypeViews/{field_type}`` + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + Output only. The asset field type of the + asset field type view. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + field_type = proto.Field( + proto.ENUM, + number=3, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_group.py b/google/ads/googleads/v12/resources/types/asset_group.py new file mode 100644 index 000000000..2ccc28aa1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_group.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ad_strength as gage_ad_strength +from google.ads.googleads.v12.enums.types import asset_group_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetGroup",}, +) + + +class AssetGroup(proto.Message): + r"""An asset group. + AssetGroupAsset is used to link an asset to the asset group. + AssetGroupSignal is used to associate a signal to an asset + group. + + Attributes: + resource_name (str): + Immutable. The resource name of the asset group. Asset group + resource names have the form: + + ``customers/{customer_id}/assetGroups/{asset_group_id}`` + id (int): + Output only. The ID of the asset group. + campaign (str): + Immutable. The campaign with which this asset + group is associated. The asset which is linked + to the asset group. + name (str): + Required. Name of the asset group. Required. + It must have a minimum length of 1 and maximum + length of 128. It must be unique under a + campaign. + final_urls (Sequence[str]): + A list of final URLs after all cross domain + redirects. In performance max, by default, the + urls are eligible for expansion unless opted + out. + final_mobile_urls (Sequence[str]): + A list of final mobile URLs after all cross + domain redirects. In performance max, by + default, the urls are eligible for expansion + unless opted out. + status (google.ads.googleads.v12.enums.types.AssetGroupStatusEnum.AssetGroupStatus): + The status of the asset group. + path1 (str): + First part of text that may appear appended + to the url displayed in the ad. + path2 (str): + Second part of text that may appear appended + to the url displayed in the ad. This field can + only be set when path1 is set. + ad_strength (google.ads.googleads.v12.enums.types.AdStrengthEnum.AdStrength): + Output only. Overall ad strength of this + asset group. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=9,) + campaign = proto.Field(proto.STRING, number=2,) + name = proto.Field(proto.STRING, number=3,) + final_urls = proto.RepeatedField(proto.STRING, number=4,) + final_mobile_urls = proto.RepeatedField(proto.STRING, number=5,) + status = proto.Field( + proto.ENUM, + number=6, + enum=asset_group_status.AssetGroupStatusEnum.AssetGroupStatus, + ) + path1 = proto.Field(proto.STRING, number=7,) + path2 = proto.Field(proto.STRING, number=8,) + ad_strength = proto.Field( + proto.ENUM, number=10, enum=gage_ad_strength.AdStrengthEnum.AdStrength, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_group_asset.py b/google/ads/googleads/v12/resources/types/asset_group_asset.py new file mode 100644 index 000000000..047567208 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_group_asset.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + policy_summary as gagc_policy_summary, +) +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_link_status +from google.ads.googleads.v12.enums.types import asset_performance_label + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupAsset",}, +) + + +class AssetGroupAsset(proto.Message): + r"""AssetGroupAsset is the link between an asset and an asset + group. Adding an AssetGroupAsset links an asset with an asset + group. + + Attributes: + resource_name (str): + Immutable. The resource name of the asset group asset. Asset + group asset resource name have the form: + + ``customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}`` + asset_group (str): + Immutable. The asset group which this asset + group asset is linking. + asset (str): + Immutable. The asset which this asset group + asset is linking. + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + The description of the placement of the asset within the + asset group. For example: HEADLINE, YOUTUBE_VIDEO etc + status (google.ads.googleads.v12.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + The status of the link between an asset and + asset group. + performance_label (google.ads.googleads.v12.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): + Output only. The performance of this asset + group asset. + policy_summary (google.ads.googleads.v12.common.types.PolicySummary): + Output only. The policy information for this + asset group asset. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group = proto.Field(proto.STRING, number=2,) + asset = proto.Field(proto.STRING, number=3,) + field_type = proto.Field( + proto.ENUM, + number=4, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=asset_link_status.AssetLinkStatusEnum.AssetLinkStatus, + ) + performance_label = proto.Field( + proto.ENUM, + number=6, + enum=asset_performance_label.AssetPerformanceLabelEnum.AssetPerformanceLabel, + ) + policy_summary = proto.Field( + proto.MESSAGE, number=7, message=gagc_policy_summary.PolicySummary, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_group_listing_group_filter.py b/google/ads/googleads/v12/resources/types/asset_group_listing_group_filter.py new file mode 100644 index 000000000..c1750d887 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_group_listing_group_filter.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + listing_group_filter_bidding_category_level, +) +from google.ads.googleads.v12.enums.types import ( + listing_group_filter_custom_attribute_index, +) +from google.ads.googleads.v12.enums.types import ( + listing_group_filter_product_channel, +) +from google.ads.googleads.v12.enums.types import ( + listing_group_filter_product_condition, +) +from google.ads.googleads.v12.enums.types import ( + listing_group_filter_product_type_level, +) +from google.ads.googleads.v12.enums.types import listing_group_filter_type_enum +from google.ads.googleads.v12.enums.types import listing_group_filter_vertical + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupListingGroupFilter", "ListingGroupFilterDimension",}, +) + + +class AssetGroupListingGroupFilter(proto.Message): + r"""AssetGroupListingGroupFilter represents a listing group + filter tree node in an asset group. + + Attributes: + resource_name (str): + Immutable. The resource name of the asset group listing + group filter. Asset group listing group filter resource name + have the form: + + ``customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}`` + asset_group (str): + Immutable. The asset group which this asset + group listing group filter is part of. + id (int): + Output only. The ID of the + ListingGroupFilter. + type_ (google.ads.googleads.v12.enums.types.ListingGroupFilterTypeEnum.ListingGroupFilterType): + Immutable. Type of a listing group filter + node. + vertical (google.ads.googleads.v12.enums.types.ListingGroupFilterVerticalEnum.ListingGroupFilterVertical): + Immutable. The vertical the current node tree + represents. All nodes in the same tree must + belong to the same vertical. + case_value (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension): + Dimension value with which this listing group + is refining its parent. Undefined for the root + group. + parent_listing_group_filter (str): + Immutable. Resource name of the parent + listing group subdivision. Null for the root + listing group filter node. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group = proto.Field(proto.STRING, number=2,) + id = proto.Field(proto.INT64, number=3,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=listing_group_filter_type_enum.ListingGroupFilterTypeEnum.ListingGroupFilterType, + ) + vertical = proto.Field( + proto.ENUM, + number=5, + enum=listing_group_filter_vertical.ListingGroupFilterVerticalEnum.ListingGroupFilterVertical, + ) + case_value = proto.Field( + proto.MESSAGE, number=6, message="ListingGroupFilterDimension", + ) + parent_listing_group_filter = proto.Field(proto.STRING, number=7,) + + +class ListingGroupFilterDimension(proto.Message): + r"""Listing dimensions for the asset group listing group filter. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + product_bidding_category (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductBiddingCategory): + Bidding category of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_brand (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductBrand): + Brand of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_channel (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductChannel): + Locality of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_condition (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductCondition): + Condition of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_custom_attribute (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductCustomAttribute): + Custom attribute of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_item_id (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductItemId): + Item id of a product offer. + + This field is a member of `oneof`_ ``dimension``. + product_type (google.ads.googleads.v12.resources.types.ListingGroupFilterDimension.ProductType): + Type of a product offer. + + This field is a member of `oneof`_ ``dimension``. + """ + + class ProductBiddingCategory(proto.Message): + r"""One element of a bidding category at a certain level. + Top-level categories are at level 1, their children at level 2, + and so on. We currently support up to 5 levels. The user must + specify a dimension type that indicates the level of the + category. All cases of the same subdivision must have the same + dimension type (category level). + + Attributes: + id (int): + ID of the product bidding category. + + This ID is equivalent to the google_product_category ID as + described in this article: + https://support.google.com/merchants/answer/6324436 + + This field is a member of `oneof`_ ``_id``. + level (google.ads.googleads.v12.enums.types.ListingGroupFilterBiddingCategoryLevelEnum.ListingGroupFilterBiddingCategoryLevel): + Indicates the level of the category in the + taxonomy. + """ + + id = proto.Field(proto.INT64, number=1, optional=True,) + level = proto.Field( + proto.ENUM, + number=2, + enum=listing_group_filter_bidding_category_level.ListingGroupFilterBiddingCategoryLevelEnum.ListingGroupFilterBiddingCategoryLevel, + ) + + class ProductBrand(proto.Message): + r"""Brand of the product. + + Attributes: + value (str): + String value of the product brand. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + class ProductChannel(proto.Message): + r"""Locality of a product offer. + + Attributes: + channel (google.ads.googleads.v12.enums.types.ListingGroupFilterProductChannelEnum.ListingGroupFilterProductChannel): + Value of the locality. + """ + + channel = proto.Field( + proto.ENUM, + number=1, + enum=listing_group_filter_product_channel.ListingGroupFilterProductChannelEnum.ListingGroupFilterProductChannel, + ) + + class ProductCondition(proto.Message): + r"""Condition of a product offer. + + Attributes: + condition (google.ads.googleads.v12.enums.types.ListingGroupFilterProductConditionEnum.ListingGroupFilterProductCondition): + Value of the condition. + """ + + condition = proto.Field( + proto.ENUM, + number=1, + enum=listing_group_filter_product_condition.ListingGroupFilterProductConditionEnum.ListingGroupFilterProductCondition, + ) + + class ProductCustomAttribute(proto.Message): + r"""Custom attribute of a product offer. + + Attributes: + value (str): + String value of the product custom attribute. + + This field is a member of `oneof`_ ``_value``. + index (google.ads.googleads.v12.enums.types.ListingGroupFilterCustomAttributeIndexEnum.ListingGroupFilterCustomAttributeIndex): + Indicates the index of the custom attribute. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + index = proto.Field( + proto.ENUM, + number=2, + enum=listing_group_filter_custom_attribute_index.ListingGroupFilterCustomAttributeIndexEnum.ListingGroupFilterCustomAttributeIndex, + ) + + class ProductItemId(proto.Message): + r"""Item id of a product offer. + + Attributes: + value (str): + Value of the id. + + This field is a member of `oneof`_ ``_value``. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + + class ProductType(proto.Message): + r"""Type of a product offer. + + Attributes: + value (str): + Value of the type. + + This field is a member of `oneof`_ ``_value``. + level (google.ads.googleads.v12.enums.types.ListingGroupFilterProductTypeLevelEnum.ListingGroupFilterProductTypeLevel): + Level of the type. + """ + + value = proto.Field(proto.STRING, number=1, optional=True,) + level = proto.Field( + proto.ENUM, + number=2, + enum=listing_group_filter_product_type_level.ListingGroupFilterProductTypeLevelEnum.ListingGroupFilterProductTypeLevel, + ) + + product_bidding_category = proto.Field( + proto.MESSAGE, + number=1, + oneof="dimension", + message=ProductBiddingCategory, + ) + product_brand = proto.Field( + proto.MESSAGE, number=2, oneof="dimension", message=ProductBrand, + ) + product_channel = proto.Field( + proto.MESSAGE, number=3, oneof="dimension", message=ProductChannel, + ) + product_condition = proto.Field( + proto.MESSAGE, number=4, oneof="dimension", message=ProductCondition, + ) + product_custom_attribute = proto.Field( + proto.MESSAGE, + number=5, + oneof="dimension", + message=ProductCustomAttribute, + ) + product_item_id = proto.Field( + proto.MESSAGE, number=6, oneof="dimension", message=ProductItemId, + ) + product_type = proto.Field( + proto.MESSAGE, number=7, oneof="dimension", message=ProductType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_group_product_group_view.py b/google/ads/googleads/v12/resources/types/asset_group_product_group_view.py new file mode 100644 index 000000000..7314953e2 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_group_product_group_view.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupProductGroupView",}, +) + + +class AssetGroupProductGroupView(proto.Message): + r"""An asset group product group view. + + Attributes: + resource_name (str): + Output only. The resource name of the asset group product + group view. Asset group product group view resource names + have the form: + + ``customers/{customer_id}/assetGroupProductGroupViews/{asset_group_id}~{listing_group_filter_id}`` + asset_group (str): + Output only. The asset group associated with + the listing group filter. + asset_group_listing_group_filter (str): + Output only. The resource name of the asset + group listing group filter. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group = proto.Field(proto.STRING, number=2,) + asset_group_listing_group_filter = proto.Field(proto.STRING, number=4,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_group_signal.py b/google/ads/googleads/v12/resources/types/asset_group_signal.py new file mode 100644 index 000000000..c813c1e72 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_group_signal.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetGroupSignal",}, +) + + +class AssetGroupSignal(proto.Message): + r"""AssetGroupSignal represents a signal in an asset group. The + existence of a signal tells the performance max campaign who's + most likely to convert. Performance Max uses the signal to look + for new people with similar or stronger intent to find + conversions across Search, Display, Video, and more. + + Attributes: + resource_name (str): + Immutable. The resource name of the asset group signal. + Asset group signal resource name have the form: + + ``customers/{customer_id}/assetGroupSignals/{asset_group_id}~{signal_id}`` + asset_group (str): + Immutable. The asset group which this asset + group signal belongs to. + audience (google.ads.googleads.v12.common.types.AudienceInfo): + Immutable. The signal(audience criterion) to + be used by the performance max campaign. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group = proto.Field(proto.STRING, number=2,) + audience = proto.Field( + proto.MESSAGE, number=3, message=criteria.AudienceInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_set.py b/google/ads/googleads/v12/resources/types/asset_set.py new file mode 100644 index 000000000..2b657a95b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_set.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import asset_set_types +from google.ads.googleads.v12.enums.types import asset_set_status +from google.ads.googleads.v12.enums.types import asset_set_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetSet",}, +) + + +class AssetSet(proto.Message): + r"""An asset set representing a collection of assets. + Use AssetSetAsset to link an asset to the asset set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + id (int): + Output only. The ID of the asset set. + resource_name (str): + Immutable. The resource name of the asset set. Asset set + resource names have the form: + + ``customers/{customer_id}/assetSets/{asset_set_id}`` + name (str): + Required. Name of the asset set. Required. It + must have a minimum length of 1 and maximum + length of 128. + type_ (google.ads.googleads.v12.enums.types.AssetSetTypeEnum.AssetSetType): + Required. Immutable. The type of the asset + set. Required. + status (google.ads.googleads.v12.enums.types.AssetSetStatusEnum.AssetSetStatus): + Output only. The status of the asset set. + Read-only. + merchant_center_feed (google.ads.googleads.v12.resources.types.AssetSet.MerchantCenterFeed): + Merchant ID and Feed Label from Google + Merchant Center. + location_group_parent_asset_set_id (int): + Immutable. Parent asset set id for the asset + set where the elements of this asset set come + from. For example: the sync level location + AssetSet id where the the elements in + LocationGroup AssetSet come from. This field is + required and only applicable for Location Group + typed AssetSet. + location_set (google.ads.googleads.v12.common.types.LocationSet): + Location asset set data. This will be used for sync level + location set. This can only be set if AssetSet's type is + LOCATION_SYNC. + + This field is a member of `oneof`_ ``asset_set_source``. + business_profile_location_group (google.ads.googleads.v12.common.types.BusinessProfileLocationGroup): + Business Profile location group asset set + data. + + This field is a member of `oneof`_ ``asset_set_source``. + chain_location_group (google.ads.googleads.v12.common.types.ChainLocationGroup): + Represents information about a Chain dynamic location group. + Only applicable if the sync level AssetSet's type is + LOCATION_SYNC and sync source is chain. + + This field is a member of `oneof`_ ``asset_set_source``. + """ + + class MerchantCenterFeed(proto.Message): + r"""Merchant ID and Feed Label from Google Merchant Center. + + Attributes: + merchant_id (int): + Required. Merchant ID from Google Merchant + Center + feed_label (str): + Optional. Feed Label from Google Merchant + Center. + + This field is a member of `oneof`_ ``_feed_label``. + """ + + merchant_id = proto.Field(proto.INT64, number=1,) + feed_label = proto.Field(proto.STRING, number=2, optional=True,) + + id = proto.Field(proto.INT64, number=6,) + resource_name = proto.Field(proto.STRING, number=1,) + name = proto.Field(proto.STRING, number=2,) + type_ = proto.Field( + proto.ENUM, number=3, enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_set_status.AssetSetStatusEnum.AssetSetStatus, + ) + merchant_center_feed = proto.Field( + proto.MESSAGE, number=5, message=MerchantCenterFeed, + ) + location_group_parent_asset_set_id = proto.Field(proto.INT64, number=10,) + location_set = proto.Field( + proto.MESSAGE, + number=7, + oneof="asset_set_source", + message=asset_set_types.LocationSet, + ) + business_profile_location_group = proto.Field( + proto.MESSAGE, + number=8, + oneof="asset_set_source", + message=asset_set_types.BusinessProfileLocationGroup, + ) + chain_location_group = proto.Field( + proto.MESSAGE, + number=9, + oneof="asset_set_source", + message=asset_set_types.ChainLocationGroup, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_set_asset.py b/google/ads/googleads/v12/resources/types/asset_set_asset.py new file mode 100644 index 000000000..52ab68ba3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_set_asset.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_set_asset_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetSetAsset",}, +) + + +class AssetSetAsset(proto.Message): + r"""AssetSetAsset is the link between an asset and an asset set. + Adding an AssetSetAsset links an asset with an asset set. + + Attributes: + resource_name (str): + Immutable. The resource name of the asset set asset. Asset + set asset resource names have the form: + + ``customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}`` + asset_set (str): + Immutable. The asset set which this asset set + asset is linking to. + asset (str): + Immutable. The asset which this asset set + asset is linking to. + status (google.ads.googleads.v12.enums.types.AssetSetAssetStatusEnum.AssetSetAssetStatus): + Output only. The status of the asset set + asset. Read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_set = proto.Field(proto.STRING, number=2,) + asset = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_set_asset_status.AssetSetAssetStatusEnum.AssetSetAssetStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/asset_set_type_view.py b/google/ads/googleads/v12/resources/types/asset_set_type_view.py new file mode 100644 index 000000000..42793c119 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/asset_set_type_view.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + asset_set_type as gage_asset_set_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"AssetSetTypeView",}, +) + + +class AssetSetTypeView(proto.Message): + r"""An asset set type view. + This view reports non-overcounted metrics for each asset set + type. Child asset set types are not included in this report. + Their stats are aggregated under the parent asset set type. + + Attributes: + resource_name (str): + Output only. The resource name of the asset set type view. + Asset set type view resource names have the form: + + ``customers/{customer_id}/assetSetTypeViews/{asset_set_type}`` + asset_set_type (google.ads.googleads.v12.enums.types.AssetSetTypeEnum.AssetSetType): + Output only. The asset set type of the asset + set type view. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_set_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/audience.py b/google/ads/googleads/v12/resources/types/audience.py new file mode 100644 index 000000000..fa6d0e80d --- /dev/null +++ b/google/ads/googleads/v12/resources/types/audience.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import audiences +from google.ads.googleads.v12.enums.types import audience_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Audience",}, +) + + +class Audience(proto.Message): + r"""Audience is an effective targeting option that lets you + intersect different segment attributes, such as detailed + demographics and affinities, to create audiences that represent + sections of your target segments. + + Attributes: + resource_name (str): + Immutable. The resource name of the audience. Audience names + have the form: + + ``customers/{customer_id}/audiences/{audience_id}`` + id (int): + Output only. ID of the audience. + status (google.ads.googleads.v12.enums.types.AudienceStatusEnum.AudienceStatus): + Output only. Status of this audience. + Indicates whether the audience is enabled or + removed. + name (str): + Required. Name of the audience. It should be + unique across all audiences. It must have a + minimum length of 1 and maximum length of 255. + description (str): + Description of this audience. + dimensions (Sequence[google.ads.googleads.v12.common.types.AudienceDimension]): + Positive dimensions specifying the audience + composition. + exclusion_dimension (google.ads.googleads.v12.common.types.AudienceExclusionDimension): + Negative dimension specifying the audience + composition. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + status = proto.Field( + proto.ENUM, + number=3, + enum=audience_status.AudienceStatusEnum.AudienceStatus, + ) + name = proto.Field(proto.STRING, number=4,) + description = proto.Field(proto.STRING, number=5,) + dimensions = proto.RepeatedField( + proto.MESSAGE, number=6, message=audiences.AudienceDimension, + ) + exclusion_dimension = proto.Field( + proto.MESSAGE, number=7, message=audiences.AudienceExclusionDimension, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/batch_job.py b/google/ads/googleads/v12/resources/types/batch_job.py new file mode 100644 index 000000000..3c688f448 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/batch_job.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import batch_job_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BatchJob",}, +) + + +class BatchJob(proto.Message): + r"""A list of mutates being processed asynchronously. The mutates + are uploaded by the user. The mutates themselves aren't readable + and the results of the job can only be read using + BatchJobService.ListBatchJobResults. + + Attributes: + resource_name (str): + Immutable. The resource name of the batch job. Batch job + resource names have the form: + + ``customers/{customer_id}/batchJobs/{batch_job_id}`` + id (int): + Output only. ID of this batch job. + + This field is a member of `oneof`_ ``_id``. + next_add_sequence_token (str): + Output only. The next sequence token to use + when adding operations. Only set when the batch + job status is PENDING. + + This field is a member of `oneof`_ ``_next_add_sequence_token``. + metadata (google.ads.googleads.v12.resources.types.BatchJob.BatchJobMetadata): + Output only. Contains additional information + about this batch job. + status (google.ads.googleads.v12.enums.types.BatchJobStatusEnum.BatchJobStatus): + Output only. Status of this batch job. + long_running_operation (str): + Output only. The resource name of the + long-running operation that can be used to poll + for completion. Only set when the batch job + status is RUNNING or DONE. + + This field is a member of `oneof`_ ``_long_running_operation``. + """ + + class BatchJobMetadata(proto.Message): + r"""Additional information about the batch job. This message is + also used as metadata returned in batch job Long Running + Operations. + + Attributes: + creation_date_time (str): + Output only. The time when this batch job was + created. Formatted as yyyy-mm-dd hh:mm:ss. + Example: "2018-03-05 09:15:00". + + This field is a member of `oneof`_ ``_creation_date_time``. + start_date_time (str): + Output only. The time when this batch job + started running. Formatted as yyyy-mm-dd + hh:mm:ss. Example: "2018-03-05 09:15:30". + + This field is a member of `oneof`_ ``_start_date_time``. + completion_date_time (str): + Output only. The time when this batch job was + completed. Formatted as yyyy-MM-dd HH:mm:ss. + Example: "2018-03-05 09:16:00". + + This field is a member of `oneof`_ ``_completion_date_time``. + estimated_completion_ratio (float): + Output only. The fraction (between 0.0 and + 1.0) of mutates that have been processed. This + is empty if the job hasn't started running yet. + + This field is a member of `oneof`_ ``_estimated_completion_ratio``. + operation_count (int): + Output only. The number of mutate operations + in the batch job. + + This field is a member of `oneof`_ ``_operation_count``. + executed_operation_count (int): + Output only. The number of mutate operations + executed by the batch job. Present only if the + job has started running. + + This field is a member of `oneof`_ ``_executed_operation_count``. + """ + + creation_date_time = proto.Field(proto.STRING, number=8, optional=True,) + start_date_time = proto.Field(proto.STRING, number=7, optional=True,) + completion_date_time = proto.Field( + proto.STRING, number=9, optional=True, + ) + estimated_completion_ratio = proto.Field( + proto.DOUBLE, number=10, optional=True, + ) + operation_count = proto.Field(proto.INT64, number=11, optional=True,) + executed_operation_count = proto.Field( + proto.INT64, number=12, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=7, optional=True,) + next_add_sequence_token = proto.Field( + proto.STRING, number=8, optional=True, + ) + metadata = proto.Field(proto.MESSAGE, number=4, message=BatchJobMetadata,) + status = proto.Field( + proto.ENUM, + number=5, + enum=batch_job_status.BatchJobStatusEnum.BatchJobStatus, + ) + long_running_operation = proto.Field(proto.STRING, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/bidding_data_exclusion.py b/google/ads/googleads/v12/resources/types/bidding_data_exclusion.py new file mode 100644 index 000000000..7bf7639f3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/bidding_data_exclusion.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import advertising_channel_type +from google.ads.googleads.v12.enums.types import device +from google.ads.googleads.v12.enums.types import seasonality_event_scope +from google.ads.googleads.v12.enums.types import seasonality_event_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BiddingDataExclusion",}, +) + + +class BiddingDataExclusion(proto.Message): + r"""Represents a bidding data exclusion. + See "About data exclusions" at + https://support.google.com/google-ads/answer/10370710. + + Attributes: + resource_name (str): + Immutable. The resource name of the data exclusion. Data + exclusion resource names have the form: + + ``customers/{customer_id}/biddingDataExclusions/{data_exclusion_id}`` + data_exclusion_id (int): + Output only. The ID of the data exclusion. + scope (google.ads.googleads.v12.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): + The scope of the data exclusion. + status (google.ads.googleads.v12.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): + Output only. The status of the data + exclusion. + start_date_time (str): + Required. The inclusive start time of the + data exclusion in yyyy-MM-dd HH:mm:ss format. + A data exclusion is backward looking and should + be used for events that start in the past and + end either in the past or future. + end_date_time (str): + Required. The exclusive end time of the data exclusion in + yyyy-MM-dd HH:mm:ss format. + + The length of [start_date_time, end_date_time) interval must + be within (0, 14 days]. + name (str): + The name of the data exclusion. The name can + be at most 255 characters. + description (str): + The description of the data exclusion. The + description can be at most 2048 characters. + devices (Sequence[google.ads.googleads.v12.enums.types.DeviceEnum.Device]): + If not specified, all devices will be + included in this exclusion. Otherwise, only the + specified targeted devices will be included in + this exclusion. + campaigns (Sequence[str]): + The data exclusion will apply to the campaigns listed when + the scope of this exclusion is CAMPAIGN. The maximum number + of campaigns per event is 2000. Note: a data exclusion with + both advertising_channel_types and campaign_ids is not + supported. + advertising_channel_types (Sequence[google.ads.googleads.v12.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): + The data_exclusion will apply to all the campaigns under the + listed channels retroactively as well as going forward when + the scope of this exclusion is CHANNEL. The supported + advertising channel types are DISPLAY, SEARCH and SHOPPING. + Note: a data exclusion with both advertising_channel_types + and campaign_ids is not supported. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + data_exclusion_id = proto.Field(proto.INT64, number=2,) + scope = proto.Field( + proto.ENUM, + number=3, + enum=seasonality_event_scope.SeasonalityEventScopeEnum.SeasonalityEventScope, + ) + status = proto.Field( + proto.ENUM, + number=4, + enum=seasonality_event_status.SeasonalityEventStatusEnum.SeasonalityEventStatus, + ) + start_date_time = proto.Field(proto.STRING, number=5,) + end_date_time = proto.Field(proto.STRING, number=6,) + name = proto.Field(proto.STRING, number=7,) + description = proto.Field(proto.STRING, number=8,) + devices = proto.RepeatedField( + proto.ENUM, number=9, enum=device.DeviceEnum.Device, + ) + campaigns = proto.RepeatedField(proto.STRING, number=10,) + advertising_channel_types = proto.RepeatedField( + proto.ENUM, + number=11, + enum=advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/bidding_seasonality_adjustment.py b/google/ads/googleads/v12/resources/types/bidding_seasonality_adjustment.py new file mode 100644 index 000000000..989377744 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/bidding_seasonality_adjustment.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import advertising_channel_type +from google.ads.googleads.v12.enums.types import device +from google.ads.googleads.v12.enums.types import seasonality_event_scope +from google.ads.googleads.v12.enums.types import seasonality_event_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BiddingSeasonalityAdjustment",}, +) + + +class BiddingSeasonalityAdjustment(proto.Message): + r"""Represents a bidding seasonality adjustment. + See "About seasonality adjustments" at + https://support.google.com/google-ads/answer/10369906. + + Attributes: + resource_name (str): + Immutable. The resource name of the seasonality adjustment. + Seasonality adjustment resource names have the form: + + ``customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_adjustment_id}`` + seasonality_adjustment_id (int): + Output only. The ID of the seasonality + adjustment. + scope (google.ads.googleads.v12.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): + The scope of the seasonality adjustment. + status (google.ads.googleads.v12.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): + Output only. The status of the seasonality + adjustment. + start_date_time (str): + Required. The inclusive start time of the + seasonality adjustment in yyyy-MM-dd HH:mm:ss + format. + A seasonality adjustment is forward looking and + should be used for events that start and end in + the future. + end_date_time (str): + Required. The exclusive end time of the seasonality + adjustment in yyyy-MM-dd HH:mm:ss format. + + The length of [start_date_time, end_date_time) interval must + be within (0, 14 days]. + name (str): + The name of the seasonality adjustment. The + name can be at most 255 characters. + description (str): + The description of the seasonality + adjustment. The description can be at most 2048 + characters. + devices (Sequence[google.ads.googleads.v12.enums.types.DeviceEnum.Device]): + If not specified, all devices will be + included in this adjustment. Otherwise, only the + specified targeted devices will be included in + this adjustment. + conversion_rate_modifier (float): + Conversion rate modifier estimated based on + expected conversion rate changes. When this + field is unset or set to 1.0 no adjustment will + be applied to traffic. The allowed range is 0.1 + to 10.0. + campaigns (Sequence[str]): + The seasonality adjustment will apply to the campaigns + listed when the scope of this adjustment is CAMPAIGN. The + maximum number of campaigns per event is 2000. Note: a + seasonality adjustment with both advertising_channel_types + and campaign_ids is not supported. + advertising_channel_types (Sequence[google.ads.googleads.v12.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): + The seasonality adjustment will apply to all the campaigns + under the listed channels retroactively as well as going + forward when the scope of this adjustment is CHANNEL. The + supported advertising channel types are DISPLAY, SEARCH and + SHOPPING. Note: a seasonality adjustment with both + advertising_channel_types and campaign_ids is not supported. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + seasonality_adjustment_id = proto.Field(proto.INT64, number=2,) + scope = proto.Field( + proto.ENUM, + number=3, + enum=seasonality_event_scope.SeasonalityEventScopeEnum.SeasonalityEventScope, + ) + status = proto.Field( + proto.ENUM, + number=4, + enum=seasonality_event_status.SeasonalityEventStatusEnum.SeasonalityEventStatus, + ) + start_date_time = proto.Field(proto.STRING, number=5,) + end_date_time = proto.Field(proto.STRING, number=6,) + name = proto.Field(proto.STRING, number=7,) + description = proto.Field(proto.STRING, number=8,) + devices = proto.RepeatedField( + proto.ENUM, number=9, enum=device.DeviceEnum.Device, + ) + conversion_rate_modifier = proto.Field(proto.DOUBLE, number=10,) + campaigns = proto.RepeatedField(proto.STRING, number=11,) + advertising_channel_types = proto.RepeatedField( + proto.ENUM, + number=12, + enum=advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/bidding_strategy.py b/google/ads/googleads/v12/resources/types/bidding_strategy.py new file mode 100644 index 000000000..9952f3392 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/bidding_strategy.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import bidding +from google.ads.googleads.v12.enums.types import bidding_strategy_status +from google.ads.googleads.v12.enums.types import bidding_strategy_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategy",}, +) + + +class BiddingStrategy(proto.Message): + r"""A bidding strategy. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the bidding strategy. + Bidding strategy resource names have the form: + + ``customers/{customer_id}/biddingStrategies/{bidding_strategy_id}`` + id (int): + Output only. The ID of the bidding strategy. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the bidding strategy. + All bidding strategies within an account must be + named distinctly. + The length of this string should be between 1 + and 255, inclusive, in UTF-8 bytes, (trimmed). + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v12.enums.types.BiddingStrategyStatusEnum.BiddingStrategyStatus): + Output only. The status of the bidding + strategy. + This field is read-only. + type_ (google.ads.googleads.v12.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + Output only. The type of the bidding + strategy. Create a bidding strategy by setting + the bidding scheme. + This field is read-only. + currency_code (str): + Immutable. The currency used by the bidding strategy (ISO + 4217 three-letter code). + + For bidding strategies in manager customers, this currency + can be set on creation and defaults to the manager + customer's currency. For serving customers, this field + cannot be set; all strategies in a serving customer + implicitly use the serving customer's currency. In all cases + the effective_currency_code field returns the currency used + by the strategy. + effective_currency_code (str): + Output only. The currency used by the bidding strategy (ISO + 4217 three-letter code). + + For bidding strategies in manager customers, this is the + currency set by the advertiser when creating the strategy. + For serving customers, this is the customer's currency_code. + + Bidding strategy metrics are reported in this currency. + + This field is read-only. + + This field is a member of `oneof`_ ``_effective_currency_code``. + aligned_campaign_budget_id (int): + ID of the campaign budget that this portfolio + bidding strategy is aligned with. When a + portfolio and a campaign budget are aligned, + that means that they are attached to the same + set of campaigns. After a bidding strategy is + aligned with a campaign budget, campaigns that + are added to the bidding strategy must also use + the aligned campaign budget. + campaign_count (int): + Output only. The number of campaigns attached + to this bidding strategy. + This field is read-only. + + This field is a member of `oneof`_ ``_campaign_count``. + non_removed_campaign_count (int): + Output only. The number of non-removed + campaigns attached to this bidding strategy. + This field is read-only. + + This field is a member of `oneof`_ ``_non_removed_campaign_count``. + enhanced_cpc (google.ads.googleads.v12.common.types.EnhancedCpc): + A bidding strategy that raises bids for + clicks that seem more likely to lead to a + conversion and lowers them for clicks where they + seem less likely. + + This field is a member of `oneof`_ ``scheme``. + maximize_conversion_value (google.ads.googleads.v12.common.types.MaximizeConversionValue): + An automated bidding strategy to help get the + most conversion value for your campaigns while + spending your budget. + + This field is a member of `oneof`_ ``scheme``. + maximize_conversions (google.ads.googleads.v12.common.types.MaximizeConversions): + An automated bidding strategy to help get the + most conversions for your campaigns while + spending your budget. + + This field is a member of `oneof`_ ``scheme``. + target_cpa (google.ads.googleads.v12.common.types.TargetCpa): + A bidding strategy that sets bids to help get + as many conversions as possible at the target + cost-per-acquisition (CPA) you set. + + This field is a member of `oneof`_ ``scheme``. + target_impression_share (google.ads.googleads.v12.common.types.TargetImpressionShare): + A bidding strategy that automatically + optimizes towards a chosen percentage of + impressions. + + This field is a member of `oneof`_ ``scheme``. + target_roas (google.ads.googleads.v12.common.types.TargetRoas): + A bidding strategy that helps you maximize + revenue while averaging a specific target Return + On Ad Spend (ROAS). + + This field is a member of `oneof`_ ``scheme``. + target_spend (google.ads.googleads.v12.common.types.TargetSpend): + A bid strategy that sets your bids to help + get as many clicks as possible within your + budget. + + This field is a member of `oneof`_ ``scheme``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=16, optional=True,) + name = proto.Field(proto.STRING, number=17, optional=True,) + status = proto.Field( + proto.ENUM, + number=15, + enum=bidding_strategy_status.BiddingStrategyStatusEnum.BiddingStrategyStatus, + ) + type_ = proto.Field( + proto.ENUM, + number=5, + enum=bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType, + ) + currency_code = proto.Field(proto.STRING, number=23,) + effective_currency_code = proto.Field( + proto.STRING, number=20, optional=True, + ) + aligned_campaign_budget_id = proto.Field(proto.INT64, number=25,) + campaign_count = proto.Field(proto.INT64, number=18, optional=True,) + non_removed_campaign_count = proto.Field( + proto.INT64, number=19, optional=True, + ) + enhanced_cpc = proto.Field( + proto.MESSAGE, number=7, oneof="scheme", message=bidding.EnhancedCpc, + ) + maximize_conversion_value = proto.Field( + proto.MESSAGE, + number=21, + oneof="scheme", + message=bidding.MaximizeConversionValue, + ) + maximize_conversions = proto.Field( + proto.MESSAGE, + number=22, + oneof="scheme", + message=bidding.MaximizeConversions, + ) + target_cpa = proto.Field( + proto.MESSAGE, number=9, oneof="scheme", message=bidding.TargetCpa, + ) + target_impression_share = proto.Field( + proto.MESSAGE, + number=48, + oneof="scheme", + message=bidding.TargetImpressionShare, + ) + target_roas = proto.Field( + proto.MESSAGE, number=11, oneof="scheme", message=bidding.TargetRoas, + ) + target_spend = proto.Field( + proto.MESSAGE, number=12, oneof="scheme", message=bidding.TargetSpend, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/bidding_strategy_simulation.py b/google/ads/googleads/v12/resources/types/bidding_strategy_simulation.py new file mode 100644 index 000000000..f5e3461d7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/bidding_strategy_simulation.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import simulation +from google.ads.googleads.v12.enums.types import simulation_modification_method +from google.ads.googleads.v12.enums.types import simulation_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BiddingStrategySimulation",}, +) + + +class BiddingStrategySimulation(proto.Message): + r"""A bidding strategy simulation. Supported combinations of simulation + type and simulation modification method are detailed below + respectively. + + 1. TARGET_CPA - UNIFORM + 2. TARGET_ROAS - UNIFORM + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the bidding strategy + simulation. Bidding strategy simulation resource names have + the form: + + ``customers/{customer_id}/biddingStrategySimulations/{bidding_strategy_id}~{type}~{modification_method}~{start_date}~{end_date}`` + bidding_strategy_id (int): + Output only. Bidding strategy shared set id + of the simulation. + type_ (google.ads.googleads.v12.enums.types.SimulationTypeEnum.SimulationType): + Output only. The field that the simulation + modifies. + modification_method (google.ads.googleads.v12.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + Output only. How the simulation modifies the + field. + start_date (str): + Output only. First day on which the + simulation is based, in YYYY-MM-DD format. + end_date (str): + Output only. Last day on which the simulation + is based, in YYYY-MM-DD format + target_cpa_point_list (google.ads.googleads.v12.common.types.TargetCpaSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_CPA. + + This field is a member of `oneof`_ ``point_list``. + target_roas_point_list (google.ads.googleads.v12.common.types.TargetRoasSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_ROAS. + + This field is a member of `oneof`_ ``point_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + bidding_strategy_id = proto.Field(proto.INT64, number=2,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=simulation_type.SimulationTypeEnum.SimulationType, + ) + modification_method = proto.Field( + proto.ENUM, + number=4, + enum=simulation_modification_method.SimulationModificationMethodEnum.SimulationModificationMethod, + ) + start_date = proto.Field(proto.STRING, number=5,) + end_date = proto.Field(proto.STRING, number=6,) + target_cpa_point_list = proto.Field( + proto.MESSAGE, + number=7, + oneof="point_list", + message=simulation.TargetCpaSimulationPointList, + ) + target_roas_point_list = proto.Field( + proto.MESSAGE, + number=8, + oneof="point_list", + message=simulation.TargetRoasSimulationPointList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/billing_setup.py b/google/ads/googleads/v12/resources/types/billing_setup.py new file mode 100644 index 000000000..62e8c8819 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/billing_setup.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import billing_setup_status +from google.ads.googleads.v12.enums.types import time_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"BillingSetup",}, +) + + +class BillingSetup(proto.Message): + r"""A billing setup, which associates a payments account and an + advertiser. A billing setup is specific to one advertiser. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the billing setup. + BillingSetup resource names have the form: + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + id (int): + Output only. The ID of the billing setup. + + This field is a member of `oneof`_ ``_id``. + status (google.ads.googleads.v12.enums.types.BillingSetupStatusEnum.BillingSetupStatus): + Output only. The status of the billing setup. + payments_account (str): + Immutable. The resource name of the payments account + associated with this billing setup. Payments resource names + have the form: + + ``customers/{customer_id}/paymentsAccounts/{payments_account_id}`` + When setting up billing, this is used to signup with an + existing payments account (and then payments_account_info + should not be set). When getting a billing setup, this and + payments_account_info will be populated. + + This field is a member of `oneof`_ ``_payments_account``. + payments_account_info (google.ads.googleads.v12.resources.types.BillingSetup.PaymentsAccountInfo): + Immutable. The payments account information associated with + this billing setup. When setting up billing, this is used to + signup with a new payments account (and then + payments_account should not be set). When getting a billing + setup, this and payments_account will be populated. + start_date_time (str): + Immutable. The start date time in yyyy-MM-dd + or yyyy-MM-dd HH:mm:ss format. Only a future + time is allowed. + + This field is a member of `oneof`_ ``start_time``. + start_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Immutable. The start time as a type. Only NOW + is allowed. + + This field is a member of `oneof`_ ``start_time``. + end_date_time (str): + Output only. The end date time in yyyy-MM-dd + or yyyy-MM-dd HH:mm:ss format. + + This field is a member of `oneof`_ ``end_time``. + end_time_type (google.ads.googleads.v12.enums.types.TimeTypeEnum.TimeType): + Output only. The end time as a type. The + only possible value is FOREVER. + + This field is a member of `oneof`_ ``end_time``. + """ + + class PaymentsAccountInfo(proto.Message): + r"""Container of payments account information for this billing. + + Attributes: + payments_account_id (str): + Output only. A 16 digit id used to identify + the payments account associated with the billing + setup. + This must be passed as a string with dashes, for + example, "1234-5678-9012-3456". + + This field is a member of `oneof`_ ``_payments_account_id``. + payments_account_name (str): + Immutable. The name of the payments account + associated with the billing setup. + This enables the user to specify a meaningful + name for a payments account to aid in + reconciling monthly invoices. + + This name will be printed in the monthly + invoices. + + This field is a member of `oneof`_ ``_payments_account_name``. + payments_profile_id (str): + Immutable. A 12 digit id used to identify the + payments profile associated with the billing + setup. + This must be passed in as a string with dashes, + for example, "1234-5678-9012". + + This field is a member of `oneof`_ ``_payments_profile_id``. + payments_profile_name (str): + Output only. The name of the payments profile + associated with the billing setup. + + This field is a member of `oneof`_ ``_payments_profile_name``. + secondary_payments_profile_id (str): + Output only. A secondary payments profile id + present in uncommon situations, for example, + when a sequential liability agreement has been + arranged. + + This field is a member of `oneof`_ ``_secondary_payments_profile_id``. + """ + + payments_account_id = proto.Field( + proto.STRING, number=6, optional=True, + ) + payments_account_name = proto.Field( + proto.STRING, number=7, optional=True, + ) + payments_profile_id = proto.Field( + proto.STRING, number=8, optional=True, + ) + payments_profile_name = proto.Field( + proto.STRING, number=9, optional=True, + ) + secondary_payments_profile_id = proto.Field( + proto.STRING, number=10, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=15, optional=True,) + status = proto.Field( + proto.ENUM, + number=3, + enum=billing_setup_status.BillingSetupStatusEnum.BillingSetupStatus, + ) + payments_account = proto.Field(proto.STRING, number=18, optional=True,) + payments_account_info = proto.Field( + proto.MESSAGE, number=12, message=PaymentsAccountInfo, + ) + start_date_time = proto.Field(proto.STRING, number=16, oneof="start_time",) + start_time_type = proto.Field( + proto.ENUM, + number=10, + oneof="start_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + end_date_time = proto.Field(proto.STRING, number=17, oneof="end_time",) + end_time_type = proto.Field( + proto.ENUM, + number=14, + oneof="end_time", + enum=time_type.TimeTypeEnum.TimeType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/call_view.py b/google/ads/googleads/v12/resources/types/call_view.py new file mode 100644 index 000000000..bc9a8c10e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/call_view.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + call_tracking_display_location as gage_call_tracking_display_location, +) +from google.ads.googleads.v12.enums.types import call_type +from google.ads.googleads.v12.enums.types import google_voice_call_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CallView",}, +) + + +class CallView(proto.Message): + r"""A call view that includes data for call tracking of call-only + ads or call extensions. + + Attributes: + resource_name (str): + Output only. The resource name of the call view. Call view + resource names have the form: + + ``customers/{customer_id}/callViews/{call_detail_id}`` + caller_country_code (str): + Output only. Country code of the caller. + caller_area_code (str): + Output only. Area code of the caller. Null if + the call duration is shorter than 15 seconds. + call_duration_seconds (int): + Output only. The advertiser-provided call + duration in seconds. + start_call_date_time (str): + Output only. The advertiser-provided call + start date time. + end_call_date_time (str): + Output only. The advertiser-provided call end + date time. + call_tracking_display_location (google.ads.googleads.v12.enums.types.CallTrackingDisplayLocationEnum.CallTrackingDisplayLocation): + Output only. The call tracking display + location. + type_ (google.ads.googleads.v12.enums.types.CallTypeEnum.CallType): + Output only. The type of the call. + call_status (google.ads.googleads.v12.enums.types.GoogleVoiceCallStatusEnum.GoogleVoiceCallStatus): + Output only. The status of the call. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + caller_country_code = proto.Field(proto.STRING, number=2,) + caller_area_code = proto.Field(proto.STRING, number=3,) + call_duration_seconds = proto.Field(proto.INT64, number=4,) + start_call_date_time = proto.Field(proto.STRING, number=5,) + end_call_date_time = proto.Field(proto.STRING, number=6,) + call_tracking_display_location = proto.Field( + proto.ENUM, + number=7, + enum=gage_call_tracking_display_location.CallTrackingDisplayLocationEnum.CallTrackingDisplayLocation, + ) + type_ = proto.Field( + proto.ENUM, number=8, enum=call_type.CallTypeEnum.CallType, + ) + call_status = proto.Field( + proto.ENUM, + number=9, + enum=google_voice_call_status.GoogleVoiceCallStatusEnum.GoogleVoiceCallStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign.py b/google/ads/googleads/v12/resources/types/campaign.py new file mode 100644 index 000000000..084da5e07 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign.py @@ -0,0 +1,975 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import bidding +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import frequency_cap +from google.ads.googleads.v12.common.types import ( + real_time_bidding_setting as gagc_real_time_bidding_setting, +) +from google.ads.googleads.v12.common.types import ( + targeting_setting as gagc_targeting_setting, +) +from google.ads.googleads.v12.enums.types import ( + ad_serving_optimization_status as gage_ad_serving_optimization_status, +) +from google.ads.googleads.v12.enums.types import ( + advertising_channel_sub_type as gage_advertising_channel_sub_type, +) +from google.ads.googleads.v12.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v12.enums.types import app_campaign_app_store +from google.ads.googleads.v12.enums.types import ( + app_campaign_bidding_strategy_goal_type, +) +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_set_type +from google.ads.googleads.v12.enums.types import ( + bidding_strategy_system_status as gage_bidding_strategy_system_status, +) +from google.ads.googleads.v12.enums.types import ( + bidding_strategy_type as gage_bidding_strategy_type, +) +from google.ads.googleads.v12.enums.types import brand_safety_suitability +from google.ads.googleads.v12.enums.types import campaign_experiment_type +from google.ads.googleads.v12.enums.types import campaign_primary_status +from google.ads.googleads.v12.enums.types import campaign_primary_status_reason +from google.ads.googleads.v12.enums.types import campaign_serving_status +from google.ads.googleads.v12.enums.types import campaign_status +from google.ads.googleads.v12.enums.types import ( + location_source_type as gage_location_source_type, +) +from google.ads.googleads.v12.enums.types import ( + negative_geo_target_type as gage_negative_geo_target_type, +) +from google.ads.googleads.v12.enums.types import optimization_goal_type +from google.ads.googleads.v12.enums.types import ( + payment_mode as gage_payment_mode, +) +from google.ads.googleads.v12.enums.types import performance_max_upgrade_status +from google.ads.googleads.v12.enums.types import ( + positive_geo_target_type as gage_positive_geo_target_type, +) +from google.ads.googleads.v12.enums.types import ( + vanity_pharma_display_url_mode as gage_vanity_pharma_display_url_mode, +) +from google.ads.googleads.v12.enums.types import ( + vanity_pharma_text as gage_vanity_pharma_text, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Campaign",}, +) + + +class Campaign(proto.Message): + r"""A campaign. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign. Campaign + resource names have the form: + + ``customers/{customer_id}/campaigns/{campaign_id}`` + id (int): + Output only. The ID of the campaign. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the campaign. + This field is required and should not be empty + when creating new campaigns. + + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + + This field is a member of `oneof`_ ``_name``. + primary_status (google.ads.googleads.v12.enums.types.CampaignPrimaryStatusEnum.CampaignPrimaryStatus): + Output only. The primary status of the + campaign. + Provides insight into why a campaign is not + serving or not serving optimally. Modification + to the campaign and its related entities might + take a while to be reflected in this status. + primary_status_reasons (Sequence[google.ads.googleads.v12.enums.types.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason]): + Output only. The primary status reasons of + the campaign. + Provides insight into why a campaign is not + serving or not serving optimally. These reasons + are aggregated to determine an overall + CampaignPrimaryStatus. + status (google.ads.googleads.v12.enums.types.CampaignStatusEnum.CampaignStatus): + The status of the campaign. + When a new campaign is added, the status + defaults to ENABLED. + serving_status (google.ads.googleads.v12.enums.types.CampaignServingStatusEnum.CampaignServingStatus): + Output only. The ad serving status of the + campaign. + bidding_strategy_system_status (google.ads.googleads.v12.enums.types.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus): + Output only. The system status of the + campaign's bidding strategy. + ad_serving_optimization_status (google.ads.googleads.v12.enums.types.AdServingOptimizationStatusEnum.AdServingOptimizationStatus): + The ad serving optimization status of the + campaign. + advertising_channel_type (google.ads.googleads.v12.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Immutable. The primary serving target for ads within the + campaign. The targeting options can be refined in + ``network_settings``. + + This field is required and should not be empty when creating + new campaigns. + + Can be set only when creating campaigns. After the campaign + is created, the field can not be changed. + advertising_channel_sub_type (google.ads.googleads.v12.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType): + Immutable. Optional refinement to + ``advertising_channel_type``. Must be a valid sub-type of + the parent channel type. + + Can be set only when creating campaigns. After campaign is + created, the field can not be changed. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + local_services_campaign_settings (google.ads.googleads.v12.resources.types.Campaign.LocalServicesCampaignSettings): + The Local Services Campaign related settings. + real_time_bidding_setting (google.ads.googleads.v12.common.types.RealTimeBiddingSetting): + Settings for Real-Time Bidding, a feature + only available for campaigns targeting the Ad + Exchange network. + network_settings (google.ads.googleads.v12.resources.types.Campaign.NetworkSettings): + The network settings for the campaign. + hotel_setting (google.ads.googleads.v12.resources.types.Campaign.HotelSettingInfo): + Immutable. The hotel setting for the + campaign. + dynamic_search_ads_setting (google.ads.googleads.v12.resources.types.Campaign.DynamicSearchAdsSetting): + The setting for controlling Dynamic Search + Ads (DSA). + shopping_setting (google.ads.googleads.v12.resources.types.Campaign.ShoppingSetting): + The setting for controlling Shopping + campaigns. + targeting_setting (google.ads.googleads.v12.common.types.TargetingSetting): + Setting for targeting related features. + audience_setting (google.ads.googleads.v12.resources.types.Campaign.AudienceSetting): + Immutable. Setting for audience related + features. + + This field is a member of `oneof`_ ``_audience_setting``. + geo_target_type_setting (google.ads.googleads.v12.resources.types.Campaign.GeoTargetTypeSetting): + The setting for ads geotargeting. + local_campaign_setting (google.ads.googleads.v12.resources.types.Campaign.LocalCampaignSetting): + The setting for local campaign. + app_campaign_setting (google.ads.googleads.v12.resources.types.Campaign.AppCampaignSetting): + The setting related to App Campaign. + labels (Sequence[str]): + Output only. The resource names of labels + attached to this campaign. + experiment_type (google.ads.googleads.v12.enums.types.CampaignExperimentTypeEnum.CampaignExperimentType): + Output only. The type of campaign: normal, + draft, or experiment. + base_campaign (str): + Output only. The resource name of the base campaign of a + draft or experiment campaign. For base campaigns, this is + equal to ``resource_name``. + + This field is read-only. + + This field is a member of `oneof`_ ``_base_campaign``. + campaign_budget (str): + The budget of the campaign. + + This field is a member of `oneof`_ ``_campaign_budget``. + bidding_strategy_type (google.ads.googleads.v12.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + Output only. The type of bidding strategy. + + A bidding strategy can be created by setting either the + bidding scheme to create a standard bidding strategy or the + ``bidding_strategy`` field to create a portfolio bidding + strategy. + + This field is read-only. + accessible_bidding_strategy (str): + Output only. Resource name of AccessibleBiddingStrategy, a + read-only view of the unrestricted attributes of the + attached portfolio bidding strategy identified by + 'bidding_strategy'. Empty, if the campaign does not use a + portfolio strategy. Unrestricted strategy attributes are + available to all customers with whom the strategy is shared + and are read from the AccessibleBiddingStrategy resource. In + contrast, restricted attributes are only available to the + owner customer of the strategy and their managers. + Restricted attributes can only be read from the + BiddingStrategy resource. + start_date (str): + The date when campaign started in serving + customer's timezone in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_start_date``. + campaign_group (str): + The campaign group this campaign belongs to. + + This field is a member of `oneof`_ ``_campaign_group``. + end_date (str): + The last day of the campaign in serving + customer's timezone in YYYY-MM-DD format. On + create, defaults to 2037-12-30, which means the + campaign will run indefinitely. To set an + existing campaign to run indefinitely, set this + field to 2037-12-30. + + This field is a member of `oneof`_ ``_end_date``. + final_url_suffix (str): + Suffix used to append query parameters to + landing pages that are served with parallel + tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + frequency_caps (Sequence[google.ads.googleads.v12.common.types.FrequencyCapEntry]): + A list that limits how often each user will + see this campaign's ads. + video_brand_safety_suitability (google.ads.googleads.v12.enums.types.BrandSafetySuitabilityEnum.BrandSafetySuitability): + Output only. 3-Tier Brand Safety setting for + the campaign. + vanity_pharma (google.ads.googleads.v12.resources.types.Campaign.VanityPharma): + Describes how unbranded pharma ads will be + displayed. + selective_optimization (google.ads.googleads.v12.resources.types.Campaign.SelectiveOptimization): + Selective optimization setting for this + campaign, which includes a set of conversion + actions to optimize this campaign towards. + optimization_goal_setting (google.ads.googleads.v12.resources.types.Campaign.OptimizationGoalSetting): + Optimization goal setting for this campaign, + which includes a set of optimization goal types. + tracking_setting (google.ads.googleads.v12.resources.types.Campaign.TrackingSetting): + Output only. Campaign-level settings for + tracking information. + payment_mode (google.ads.googleads.v12.enums.types.PaymentModeEnum.PaymentMode): + Payment mode for the campaign. + optimization_score (float): + Output only. Optimization score of the + campaign. + Optimization score is an estimate of how well a + campaign is set to perform. It ranges from 0% + (0.0) to 100% (1.0), with 100% indicating that + the campaign is performing at full potential. + This field is null for unscored campaigns. + + See "About optimization score" at + https://support.google.com/google-ads/answer/9061546. + This field is read-only. + + This field is a member of `oneof`_ ``_optimization_score``. + excluded_parent_asset_field_types (Sequence[google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType]): + The asset field types that should be excluded + from this campaign. Asset links with these field + types will not be inherited by this campaign + from the upper level. + excluded_parent_asset_set_types (Sequence[google.ads.googleads.v12.enums.types.AssetSetTypeEnum.AssetSetType]): + The asset set types that should be excluded from this + campaign. Asset set links with these types will not be + inherited by this campaign from the upper level. Location + group types (GMB_DYNAMIC_LOCATION_GROUP, + CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are + child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is + set for this field, all location group asset sets are not + allowed to be linked to this campaign, and all Location + Extension (LE) and Affiliate Location Extensions (ALE) will + not be served under this campaign. Only LOCATION_SYNC is + currently supported. + url_expansion_opt_out (bool): + Represents opting out of URL expansion to + more targeted URLs. If opted out (true), only + the final URLs in the asset group or URLs + specified in the advertiser's Google Merchant + Center or business data feeds are targeted. If + opted in (false), the entire domain will be + targeted. This field can only be set for + Performance Max campaigns, where the default + value is false. + + This field is a member of `oneof`_ ``_url_expansion_opt_out``. + performance_max_upgrade (google.ads.googleads.v12.resources.types.Campaign.PerformanceMaxUpgrade): + Output only. Information about campaigns + being upgraded to Performance Max. + bidding_strategy (str): + Portfolio bidding strategy used by campaign. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + commission (google.ads.googleads.v12.common.types.Commission): + Commission is an automatic bidding strategy + in which the advertiser pays a certain portion + of the conversion value. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpa (google.ads.googleads.v12.common.types.ManualCpa): + Standard Manual CPA bidding strategy. + Manual bidding strategy that allows advertiser + to set the bid per advertiser-specified action. + Supported only for Local Services campaigns. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpc (google.ads.googleads.v12.common.types.ManualCpc): + Standard Manual CPC bidding strategy. + Manual click-based bidding where user pays per + click. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpm (google.ads.googleads.v12.common.types.ManualCpm): + Standard Manual CPM bidding strategy. + Manual impression-based bidding where user pays + per thousand impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpv (google.ads.googleads.v12.common.types.ManualCpv): + Output only. A bidding strategy that pays a + configurable amount per video view. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + maximize_conversions (google.ads.googleads.v12.common.types.MaximizeConversions): + Standard Maximize Conversions bidding + strategy that automatically maximizes number of + conversions while spending your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + maximize_conversion_value (google.ads.googleads.v12.common.types.MaximizeConversionValue): + Standard Maximize Conversion Value bidding + strategy that automatically sets bids to + maximize revenue while spending your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpa (google.ads.googleads.v12.common.types.TargetCpa): + Standard Target CPA bidding strategy that + automatically sets bids to help get as many + conversions as possible at the target + cost-per-acquisition (CPA) you set. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_impression_share (google.ads.googleads.v12.common.types.TargetImpressionShare): + Target Impression Share bidding strategy. An + automated bidding strategy that sets bids to + achieve a chosen percentage of impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_roas (google.ads.googleads.v12.common.types.TargetRoas): + Standard Target ROAS bidding strategy that + automatically maximizes revenue while averaging + a specific target return on ad spend (ROAS). + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_spend (google.ads.googleads.v12.common.types.TargetSpend): + Standard Target Spend bidding strategy that + automatically sets your bids to help get as many + clicks as possible within your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + percent_cpc (google.ads.googleads.v12.common.types.PercentCpc): + Standard Percent Cpc bidding strategy where + bids are a fraction of the advertised price for + some good or service. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpm (google.ads.googleads.v12.common.types.TargetCpm): + A bidding strategy that automatically + optimizes cost per thousand impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + """ + + class PerformanceMaxUpgrade(proto.Message): + r"""Information about a campaign being upgraded to Performance + Max. + + Attributes: + performance_max_campaign (str): + Output only. Indicates which Performance Max + campaign the campaign is upgraded to. + pre_upgrade_campaign (str): + Output only. Indicates legacy campaign + upgraded to Performance Max. + status (google.ads.googleads.v12.enums.types.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus): + Output only. The upgrade status of a campaign + requested to be upgraded to Performance Max. + """ + + performance_max_campaign = proto.Field(proto.STRING, number=1,) + pre_upgrade_campaign = proto.Field(proto.STRING, number=2,) + status = proto.Field( + proto.ENUM, + number=3, + enum=performance_max_upgrade_status.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus, + ) + + class NetworkSettings(proto.Message): + r"""The network settings for the campaign. + + Attributes: + target_google_search (bool): + Whether ads will be served with google.com + search results. + + This field is a member of `oneof`_ ``_target_google_search``. + target_search_network (bool): + Whether ads will be served on partner sites in the Google + Search Network (requires ``target_google_search`` to also be + ``true``). + + This field is a member of `oneof`_ ``_target_search_network``. + target_content_network (bool): + Whether ads will be served on specified + placements in the Google Display Network. + Placements are specified using the Placement + criterion. + + This field is a member of `oneof`_ ``_target_content_network``. + target_partner_search_network (bool): + Whether ads will be served on the Google + Partner Network. This is available only to some + select Google partner accounts. + + This field is a member of `oneof`_ ``_target_partner_search_network``. + """ + + target_google_search = proto.Field(proto.BOOL, number=5, optional=True,) + target_search_network = proto.Field( + proto.BOOL, number=6, optional=True, + ) + target_content_network = proto.Field( + proto.BOOL, number=7, optional=True, + ) + target_partner_search_network = proto.Field( + proto.BOOL, number=8, optional=True, + ) + + class HotelSettingInfo(proto.Message): + r"""Campaign-level settings for hotel ads. + + Attributes: + hotel_center_id (int): + Immutable. The linked Hotel Center account. + + This field is a member of `oneof`_ ``_hotel_center_id``. + """ + + hotel_center_id = proto.Field(proto.INT64, number=2, optional=True,) + + class DynamicSearchAdsSetting(proto.Message): + r"""The setting for controlling Dynamic Search Ads (DSA). + + Attributes: + domain_name (str): + Required. The Internet domain name that this + setting represents, for example, "google.com" or + "www.google.com". + language_code (str): + Required. The language code specifying the + language of the domain, for example, "en". + use_supplied_urls_only (bool): + Whether the campaign uses advertiser supplied + URLs exclusively. + + This field is a member of `oneof`_ ``_use_supplied_urls_only``. + feeds (Sequence[str]): + The list of page feeds associated with the + campaign. + """ + + domain_name = proto.Field(proto.STRING, number=6,) + language_code = proto.Field(proto.STRING, number=7,) + use_supplied_urls_only = proto.Field( + proto.BOOL, number=8, optional=True, + ) + feeds = proto.RepeatedField(proto.STRING, number=9,) + + class ShoppingSetting(proto.Message): + r"""The setting for Shopping campaigns. Defines the universe of + products that can be advertised by the campaign, and how this + campaign interacts with other Shopping campaigns. + + Attributes: + merchant_id (int): + Immutable. ID of the Merchant Center account. + This field is required for create operations. + This field is immutable for Shopping campaigns. + + This field is a member of `oneof`_ ``_merchant_id``. + sales_country (str): + Sales country of products to include in the campaign. Only + one of feed_label or sales_country can be set. Field is + immutable except for clearing. Once this field is cleared, + you must use feed_label if you want to set the sales + country. + + This field is a member of `oneof`_ ``_sales_country``. + feed_label (str): + Feed label of products to include in the campaign. Only one + of feed_label or sales_country can be set. If used instead + of sales_country, the feed_label field accepts country codes + in the same format for example: 'XX'. Otherwise can be any + string used for feed label in Google Merchant Center. + campaign_priority (int): + Priority of the campaign. Campaigns with + numerically higher priorities take precedence + over those with lower priorities. This field is + required for Shopping campaigns, with values + between 0 and 2, inclusive. + This field is optional for Smart Shopping + campaigns, but must be equal to 3 if set. + + This field is a member of `oneof`_ ``_campaign_priority``. + enable_local (bool): + Whether to include local products. + + This field is a member of `oneof`_ ``_enable_local``. + use_vehicle_inventory (bool): + Immutable. Whether to target Vehicle Listing + inventory. + """ + + merchant_id = proto.Field(proto.INT64, number=5, optional=True,) + sales_country = proto.Field(proto.STRING, number=6, optional=True,) + feed_label = proto.Field(proto.STRING, number=10,) + campaign_priority = proto.Field(proto.INT32, number=7, optional=True,) + enable_local = proto.Field(proto.BOOL, number=8, optional=True,) + use_vehicle_inventory = proto.Field(proto.BOOL, number=9,) + + class TrackingSetting(proto.Message): + r"""Campaign-level settings for tracking information. + + Attributes: + tracking_url (str): + Output only. The url used for dynamic + tracking. + + This field is a member of `oneof`_ ``_tracking_url``. + """ + + tracking_url = proto.Field(proto.STRING, number=2, optional=True,) + + class GeoTargetTypeSetting(proto.Message): + r"""Represents a collection of settings related to ads + geotargeting. + + Attributes: + positive_geo_target_type (google.ads.googleads.v12.enums.types.PositiveGeoTargetTypeEnum.PositiveGeoTargetType): + The setting used for positive geotargeting in + this particular campaign. + negative_geo_target_type (google.ads.googleads.v12.enums.types.NegativeGeoTargetTypeEnum.NegativeGeoTargetType): + The setting used for negative geotargeting in + this particular campaign. + """ + + positive_geo_target_type = proto.Field( + proto.ENUM, + number=1, + enum=gage_positive_geo_target_type.PositiveGeoTargetTypeEnum.PositiveGeoTargetType, + ) + negative_geo_target_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_negative_geo_target_type.NegativeGeoTargetTypeEnum.NegativeGeoTargetType, + ) + + class LocalCampaignSetting(proto.Message): + r"""Campaign setting for local campaigns. + + Attributes: + location_source_type (google.ads.googleads.v12.enums.types.LocationSourceTypeEnum.LocationSourceType): + The location source type for this local + campaign. + """ + + location_source_type = proto.Field( + proto.ENUM, + number=1, + enum=gage_location_source_type.LocationSourceTypeEnum.LocationSourceType, + ) + + class AppCampaignSetting(proto.Message): + r"""Campaign-level settings for App Campaigns. + + Attributes: + bidding_strategy_goal_type (google.ads.googleads.v12.enums.types.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType): + Represents the goal which the bidding + strategy of this app campaign should optimize + towards. + app_id (str): + Immutable. A string that uniquely identifies + a mobile application. + + This field is a member of `oneof`_ ``_app_id``. + app_store (google.ads.googleads.v12.enums.types.AppCampaignAppStoreEnum.AppCampaignAppStore): + Immutable. The application store that + distributes this specific app. + """ + + bidding_strategy_goal_type = proto.Field( + proto.ENUM, + number=1, + enum=app_campaign_bidding_strategy_goal_type.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType, + ) + app_id = proto.Field(proto.STRING, number=4, optional=True,) + app_store = proto.Field( + proto.ENUM, + number=3, + enum=app_campaign_app_store.AppCampaignAppStoreEnum.AppCampaignAppStore, + ) + + class VanityPharma(proto.Message): + r"""Describes how unbranded pharma ads will be displayed. + + Attributes: + vanity_pharma_display_url_mode (google.ads.googleads.v12.enums.types.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode): + The display mode for vanity pharma URLs. + vanity_pharma_text (google.ads.googleads.v12.enums.types.VanityPharmaTextEnum.VanityPharmaText): + The text that will be displayed in display + URL of the text ad when website description is + the selected display mode for vanity pharma + URLs. + """ + + vanity_pharma_display_url_mode = proto.Field( + proto.ENUM, + number=1, + enum=gage_vanity_pharma_display_url_mode.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode, + ) + vanity_pharma_text = proto.Field( + proto.ENUM, + number=2, + enum=gage_vanity_pharma_text.VanityPharmaTextEnum.VanityPharmaText, + ) + + class SelectiveOptimization(proto.Message): + r"""Selective optimization setting for this campaign, which + includes a set of conversion actions to optimize this campaign + towards. + + Attributes: + conversion_actions (Sequence[str]): + The selected set of conversion actions for + optimizing this campaign. + """ + + conversion_actions = proto.RepeatedField(proto.STRING, number=2,) + + class OptimizationGoalSetting(proto.Message): + r"""Optimization goal setting for this campaign, which includes a + set of optimization goal types. + + Attributes: + optimization_goal_types (Sequence[google.ads.googleads.v12.enums.types.OptimizationGoalTypeEnum.OptimizationGoalType]): + The list of optimization goal types. + """ + + optimization_goal_types = proto.RepeatedField( + proto.ENUM, + number=1, + enum=optimization_goal_type.OptimizationGoalTypeEnum.OptimizationGoalType, + ) + + class AudienceSetting(proto.Message): + r"""Settings for the audience targeting. + + Attributes: + use_audience_grouped (bool): + Immutable. If true, this campaign uses an + Audience resource for audience targeting. If + false, this campaign may use audience segment + criteria instead. + + This field is a member of `oneof`_ ``_use_audience_grouped``. + """ + + use_audience_grouped = proto.Field(proto.BOOL, number=1, optional=True,) + + class LocalServicesCampaignSettings(proto.Message): + r"""Settings for LocalServicesCampaign subresource. + + Attributes: + category_bids (Sequence[google.ads.googleads.v12.resources.types.Campaign.CategoryBid]): + Categorical level bids associated with MANUAL_CPA bidding + strategy. + """ + + category_bids = proto.RepeatedField( + proto.MESSAGE, number=1, message="Campaign.CategoryBid", + ) + + class CategoryBid(proto.Message): + r"""Category bids in LocalServicesReportingCampaignSettings. + + Attributes: + category_id (str): + Category for which the bid will be associated with. For + example, xcat:service_area_business_plumber. + + This field is a member of `oneof`_ ``_category_id``. + manual_cpa_bid_micros (int): + Manual CPA bid for the category. Bid must be + greater than the reserve price associated for + that category. Value is in micros and in the + advertiser's currency. + + This field is a member of `oneof`_ ``_manual_cpa_bid_micros``. + """ + + category_id = proto.Field(proto.STRING, number=1, optional=True,) + manual_cpa_bid_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=59, optional=True,) + name = proto.Field(proto.STRING, number=58, optional=True,) + primary_status = proto.Field( + proto.ENUM, + number=81, + enum=campaign_primary_status.CampaignPrimaryStatusEnum.CampaignPrimaryStatus, + ) + primary_status_reasons = proto.RepeatedField( + proto.ENUM, + number=82, + enum=campaign_primary_status_reason.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=campaign_status.CampaignStatusEnum.CampaignStatus, + ) + serving_status = proto.Field( + proto.ENUM, + number=21, + enum=campaign_serving_status.CampaignServingStatusEnum.CampaignServingStatus, + ) + bidding_strategy_system_status = proto.Field( + proto.ENUM, + number=78, + enum=gage_bidding_strategy_system_status.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus, + ) + ad_serving_optimization_status = proto.Field( + proto.ENUM, + number=8, + enum=gage_ad_serving_optimization_status.AdServingOptimizationStatusEnum.AdServingOptimizationStatus, + ) + advertising_channel_type = proto.Field( + proto.ENUM, + number=9, + enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + advertising_channel_sub_type = proto.Field( + proto.ENUM, + number=10, + enum=gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType, + ) + tracking_url_template = proto.Field(proto.STRING, number=60, optional=True,) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=12, message=custom_parameter.CustomParameter, + ) + local_services_campaign_settings = proto.Field( + proto.MESSAGE, number=75, message=LocalServicesCampaignSettings, + ) + real_time_bidding_setting = proto.Field( + proto.MESSAGE, + number=39, + message=gagc_real_time_bidding_setting.RealTimeBiddingSetting, + ) + network_settings = proto.Field( + proto.MESSAGE, number=14, message=NetworkSettings, + ) + hotel_setting = proto.Field( + proto.MESSAGE, number=32, message=HotelSettingInfo, + ) + dynamic_search_ads_setting = proto.Field( + proto.MESSAGE, number=33, message=DynamicSearchAdsSetting, + ) + shopping_setting = proto.Field( + proto.MESSAGE, number=36, message=ShoppingSetting, + ) + targeting_setting = proto.Field( + proto.MESSAGE, + number=43, + message=gagc_targeting_setting.TargetingSetting, + ) + audience_setting = proto.Field( + proto.MESSAGE, number=73, optional=True, message=AudienceSetting, + ) + geo_target_type_setting = proto.Field( + proto.MESSAGE, number=47, message=GeoTargetTypeSetting, + ) + local_campaign_setting = proto.Field( + proto.MESSAGE, number=50, message=LocalCampaignSetting, + ) + app_campaign_setting = proto.Field( + proto.MESSAGE, number=51, message=AppCampaignSetting, + ) + labels = proto.RepeatedField(proto.STRING, number=61,) + experiment_type = proto.Field( + proto.ENUM, + number=17, + enum=campaign_experiment_type.CampaignExperimentTypeEnum.CampaignExperimentType, + ) + base_campaign = proto.Field(proto.STRING, number=56, optional=True,) + campaign_budget = proto.Field(proto.STRING, number=62, optional=True,) + bidding_strategy_type = proto.Field( + proto.ENUM, + number=22, + enum=gage_bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType, + ) + accessible_bidding_strategy = proto.Field(proto.STRING, number=71,) + start_date = proto.Field(proto.STRING, number=63, optional=True,) + campaign_group = proto.Field(proto.STRING, number=76, optional=True,) + end_date = proto.Field(proto.STRING, number=64, optional=True,) + final_url_suffix = proto.Field(proto.STRING, number=65, optional=True,) + frequency_caps = proto.RepeatedField( + proto.MESSAGE, number=40, message=frequency_cap.FrequencyCapEntry, + ) + video_brand_safety_suitability = proto.Field( + proto.ENUM, + number=42, + enum=brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability, + ) + vanity_pharma = proto.Field(proto.MESSAGE, number=44, message=VanityPharma,) + selective_optimization = proto.Field( + proto.MESSAGE, number=45, message=SelectiveOptimization, + ) + optimization_goal_setting = proto.Field( + proto.MESSAGE, number=54, message=OptimizationGoalSetting, + ) + tracking_setting = proto.Field( + proto.MESSAGE, number=46, message=TrackingSetting, + ) + payment_mode = proto.Field( + proto.ENUM, + number=52, + enum=gage_payment_mode.PaymentModeEnum.PaymentMode, + ) + optimization_score = proto.Field(proto.DOUBLE, number=66, optional=True,) + excluded_parent_asset_field_types = proto.RepeatedField( + proto.ENUM, + number=69, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + excluded_parent_asset_set_types = proto.RepeatedField( + proto.ENUM, + number=80, + enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + url_expansion_opt_out = proto.Field(proto.BOOL, number=72, optional=True,) + performance_max_upgrade = proto.Field( + proto.MESSAGE, number=77, message=PerformanceMaxUpgrade, + ) + bidding_strategy = proto.Field( + proto.STRING, number=67, oneof="campaign_bidding_strategy", + ) + commission = proto.Field( + proto.MESSAGE, + number=49, + oneof="campaign_bidding_strategy", + message=bidding.Commission, + ) + manual_cpa = proto.Field( + proto.MESSAGE, + number=74, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpa, + ) + manual_cpc = proto.Field( + proto.MESSAGE, + number=24, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpc, + ) + manual_cpm = proto.Field( + proto.MESSAGE, + number=25, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpm, + ) + manual_cpv = proto.Field( + proto.MESSAGE, + number=37, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpv, + ) + maximize_conversions = proto.Field( + proto.MESSAGE, + number=30, + oneof="campaign_bidding_strategy", + message=bidding.MaximizeConversions, + ) + maximize_conversion_value = proto.Field( + proto.MESSAGE, + number=31, + oneof="campaign_bidding_strategy", + message=bidding.MaximizeConversionValue, + ) + target_cpa = proto.Field( + proto.MESSAGE, + number=26, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpa, + ) + target_impression_share = proto.Field( + proto.MESSAGE, + number=48, + oneof="campaign_bidding_strategy", + message=bidding.TargetImpressionShare, + ) + target_roas = proto.Field( + proto.MESSAGE, + number=29, + oneof="campaign_bidding_strategy", + message=bidding.TargetRoas, + ) + target_spend = proto.Field( + proto.MESSAGE, + number=27, + oneof="campaign_bidding_strategy", + message=bidding.TargetSpend, + ) + percent_cpc = proto.Field( + proto.MESSAGE, + number=34, + oneof="campaign_bidding_strategy", + message=bidding.PercentCpc, + ) + target_cpm = proto.Field( + proto.MESSAGE, + number=41, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpm, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_asset.py b/google/ads/googleads/v12/resources/types/campaign_asset.py new file mode 100644 index 000000000..98cf72613 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_asset.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_link_status +from google.ads.googleads.v12.enums.types import asset_source + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignAsset",}, +) + + +class CampaignAsset(proto.Message): + r"""A link between a Campaign and an Asset. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign asset. + CampaignAsset resource names have the form: + + ``customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}`` + campaign (str): + Immutable. The campaign to which the asset is + linked. + + This field is a member of `oneof`_ ``_campaign``. + asset (str): + Immutable. The asset which is linked to the + campaign. + + This field is a member of `oneof`_ ``_asset``. + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + Immutable. Role that the asset takes under + the linked campaign. Required. + source (google.ads.googleads.v12.enums.types.AssetSourceEnum.AssetSource): + Output only. Source of the campaign asset + link. + status (google.ads.googleads.v12.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + Status of the campaign asset. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=6, optional=True,) + asset = proto.Field(proto.STRING, number=7, optional=True,) + field_type = proto.Field( + proto.ENUM, + number=4, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + source = proto.Field( + proto.ENUM, number=8, enum=asset_source.AssetSourceEnum.AssetSource, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=asset_link_status.AssetLinkStatusEnum.AssetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_asset_set.py b/google/ads/googleads/v12/resources/types/campaign_asset_set.py new file mode 100644 index 000000000..42b48ec81 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_asset_set.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_set_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignAssetSet",}, +) + + +class CampaignAssetSet(proto.Message): + r"""CampaignAssetSet is the linkage between a campaign and an + asset set. Adding a CampaignAssetSet links an asset set with a + campaign. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign asset set. + Asset set asset resource names have the form: + + ``customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}`` + campaign (str): + Immutable. The campaign to which this asset + set is linked. + asset_set (str): + Immutable. The asset set which is linked to + the campaign. + status (google.ads.googleads.v12.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + Output only. The status of the campaign asset + set asset. Read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + asset_set = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_set_link_status.AssetSetLinkStatusEnum.AssetSetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_audience_view.py b/google/ads/googleads/v12/resources/types/campaign_audience_view.py new file mode 100644 index 000000000..6d28dda26 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_audience_view.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignAudienceView",}, +) + + +class CampaignAudienceView(proto.Message): + r"""A campaign audience view. + Includes performance data from interests and remarketing lists + for Display Network and YouTube Network ads, and remarketing + lists for search ads (RLSA), aggregated by campaign and audience + criterion. This view only includes audiences attached at the + campaign level. + + Attributes: + resource_name (str): + Output only. The resource name of the campaign audience + view. Campaign audience view resource names have the form: + + ``customers/{customer_id}/campaignAudienceViews/{campaign_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_bid_modifier.py b/google/ads/googleads/v12/resources/types/campaign_bid_modifier.py new file mode 100644 index 000000000..5f57e0018 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_bid_modifier.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignBidModifier",}, +) + + +class CampaignBidModifier(proto.Message): + r"""Represents a bid-modifiable only criterion at the campaign + level. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign bid modifier. + Campaign bid modifier resource names have the form: + + ``customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}`` + campaign (str): + Output only. The campaign to which this + criterion belongs. + + This field is a member of `oneof`_ ``_campaign``. + criterion_id (int): + Output only. The ID of the criterion to bid + modify. + This field is ignored for mutates. + + This field is a member of `oneof`_ ``_criterion_id``. + bid_modifier (float): + The modifier for the bid when the criterion + matches. + + This field is a member of `oneof`_ ``_bid_modifier``. + interaction_type (google.ads.googleads.v12.common.types.InteractionTypeInfo): + Immutable. Criterion for interaction type. + Only supported for search campaigns. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=6, optional=True,) + criterion_id = proto.Field(proto.INT64, number=7, optional=True,) + bid_modifier = proto.Field(proto.DOUBLE, number=8, optional=True,) + interaction_type = proto.Field( + proto.MESSAGE, + number=5, + oneof="criterion", + message=criteria.InteractionTypeInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_budget.py b/google/ads/googleads/v12/resources/types/campaign_budget.py new file mode 100644 index 000000000..d9c3675e7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_budget.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import budget_delivery_method +from google.ads.googleads.v12.enums.types import budget_period +from google.ads.googleads.v12.enums.types import budget_status +from google.ads.googleads.v12.enums.types import budget_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignBudget",}, +) + + +class CampaignBudget(proto.Message): + r"""A campaign budget. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign budget. + Campaign budget resource names have the form: + + ``customers/{customer_id}/campaignBudgets/{campaign_budget_id}`` + id (int): + Output only. The ID of the campaign budget. + A campaign budget is created using the + CampaignBudgetService create operation and is + assigned a budget ID. A budget ID can be shared + across different campaigns; the system will then + allocate the campaign budget among different + campaigns to get optimum results. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the campaign budget. + When creating a campaign budget through + CampaignBudgetService, every explicitly shared + campaign budget must have a non-null, non-empty + name. Campaign budgets that are not explicitly + shared derive their name from the attached + campaign's name. + + The length of this string must be between 1 and + 255, inclusive, in UTF-8 bytes, (trimmed). + + This field is a member of `oneof`_ ``_name``. + amount_micros (int): + The amount of the budget, in the local + currency for the account. Amount is specified in + micros, where one million is equivalent to one + currency unit. Monthly spend is capped at 30.4 + times this amount. + + This field is a member of `oneof`_ ``_amount_micros``. + total_amount_micros (int): + The lifetime amount of the budget, in the + local currency for the account. Amount is + specified in micros, where one million is + equivalent to one currency unit. + + This field is a member of `oneof`_ ``_total_amount_micros``. + status (google.ads.googleads.v12.enums.types.BudgetStatusEnum.BudgetStatus): + Output only. The status of this campaign + budget. This field is read-only. + delivery_method (google.ads.googleads.v12.enums.types.BudgetDeliveryMethodEnum.BudgetDeliveryMethod): + The delivery method that determines the rate + at which the campaign budget is spent. + + Defaults to STANDARD if unspecified in a create + operation. + explicitly_shared (bool): + Specifies whether the budget is explicitly + shared. Defaults to true if unspecified in a + create operation. + If true, the budget was created with the purpose + of sharing across one or more campaigns. + + If false, the budget was created with the + intention of only being used with a single + campaign. The budget's name and status will stay + in sync with the campaign's name and status. + Attempting to share the budget with a second + campaign will result in an error. + + A non-shared budget can become an explicitly + shared. The same operation must also assign the + budget a name. + + A shared campaign budget can never become + non-shared. + + This field is a member of `oneof`_ ``_explicitly_shared``. + reference_count (int): + Output only. The number of campaigns actively + using the budget. + This field is read-only. + + This field is a member of `oneof`_ ``_reference_count``. + has_recommended_budget (bool): + Output only. Indicates whether there is a + recommended budget for this campaign budget. + This field is read-only. + + This field is a member of `oneof`_ ``_has_recommended_budget``. + recommended_budget_amount_micros (int): + Output only. The recommended budget amount. + If no recommendation is available, this will be + set to the budget amount. Amount is specified in + micros, where one million is equivalent to one + currency unit. + + This field is read-only. + + This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. + period (google.ads.googleads.v12.enums.types.BudgetPeriodEnum.BudgetPeriod): + Immutable. Period over which to spend the + budget. Defaults to DAILY if not specified. + recommended_budget_estimated_change_weekly_clicks (int): + Output only. The estimated change in weekly + clicks if the recommended budget is applied. + This field is read-only. + + This field is a member of `oneof`_ ``_recommended_budget_estimated_change_weekly_clicks``. + recommended_budget_estimated_change_weekly_cost_micros (int): + Output only. The estimated change in weekly + cost in micros if the recommended budget is + applied. One million is equivalent to one + currency unit. + This field is read-only. + + This field is a member of `oneof`_ ``_recommended_budget_estimated_change_weekly_cost_micros``. + recommended_budget_estimated_change_weekly_interactions (int): + Output only. The estimated change in weekly + interactions if the recommended budget is + applied. + This field is read-only. + + This field is a member of `oneof`_ ``_recommended_budget_estimated_change_weekly_interactions``. + recommended_budget_estimated_change_weekly_views (int): + Output only. The estimated change in weekly + views if the recommended budget is applied. + This field is read-only. + + This field is a member of `oneof`_ ``_recommended_budget_estimated_change_weekly_views``. + type_ (google.ads.googleads.v12.enums.types.BudgetTypeEnum.BudgetType): + Immutable. The type of the campaign budget. + aligned_bidding_strategy_id (int): + ID of the portfolio bidding strategy that + this shared campaign budget is aligned with. + When a bidding strategy and a campaign budget + are aligned, they are attached to the same set + of campaigns. After a campaign budget is aligned + with a bidding strategy, campaigns that are + added to the campaign budget must also use the + aligned bidding strategy. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=19, optional=True,) + name = proto.Field(proto.STRING, number=20, optional=True,) + amount_micros = proto.Field(proto.INT64, number=21, optional=True,) + total_amount_micros = proto.Field(proto.INT64, number=22, optional=True,) + status = proto.Field( + proto.ENUM, number=6, enum=budget_status.BudgetStatusEnum.BudgetStatus, + ) + delivery_method = proto.Field( + proto.ENUM, + number=7, + enum=budget_delivery_method.BudgetDeliveryMethodEnum.BudgetDeliveryMethod, + ) + explicitly_shared = proto.Field(proto.BOOL, number=23, optional=True,) + reference_count = proto.Field(proto.INT64, number=24, optional=True,) + has_recommended_budget = proto.Field(proto.BOOL, number=25, optional=True,) + recommended_budget_amount_micros = proto.Field( + proto.INT64, number=26, optional=True, + ) + period = proto.Field( + proto.ENUM, number=13, enum=budget_period.BudgetPeriodEnum.BudgetPeriod, + ) + recommended_budget_estimated_change_weekly_clicks = proto.Field( + proto.INT64, number=27, optional=True, + ) + recommended_budget_estimated_change_weekly_cost_micros = proto.Field( + proto.INT64, number=28, optional=True, + ) + recommended_budget_estimated_change_weekly_interactions = proto.Field( + proto.INT64, number=29, optional=True, + ) + recommended_budget_estimated_change_weekly_views = proto.Field( + proto.INT64, number=30, optional=True, + ) + type_ = proto.Field( + proto.ENUM, number=18, enum=budget_type.BudgetTypeEnum.BudgetType, + ) + aligned_bidding_strategy_id = proto.Field(proto.INT64, number=31,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_conversion_goal.py b/google/ads/googleads/v12/resources/types/campaign_conversion_goal.py new file mode 100644 index 000000000..9cb2bad4e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_conversion_goal.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import conversion_action_category +from google.ads.googleads.v12.enums.types import conversion_origin + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignConversionGoal",}, +) + + +class CampaignConversionGoal(proto.Message): + r"""The biddability setting for the specified campaign only for + all conversion actions with a matching category and origin. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign conversion + goal. Campaign conversion goal resource names have the form: + + ``customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{origin}`` + campaign (str): + Immutable. The campaign with which this + campaign conversion goal is associated. + category (google.ads.googleads.v12.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + The conversion category of this campaign + conversion goal. + origin (google.ads.googleads.v12.enums.types.ConversionOriginEnum.ConversionOrigin): + The conversion origin of this campaign + conversion goal. + biddable (bool): + The biddability of the campaign conversion + goal. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + category = proto.Field( + proto.ENUM, + number=3, + enum=conversion_action_category.ConversionActionCategoryEnum.ConversionActionCategory, + ) + origin = proto.Field( + proto.ENUM, + number=4, + enum=conversion_origin.ConversionOriginEnum.ConversionOrigin, + ) + biddable = proto.Field(proto.BOOL, number=5,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_criterion.py b/google/ads/googleads/v12/resources/types/campaign_criterion.py new file mode 100644 index 000000000..fd6d2dee5 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_criterion.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import campaign_criterion_status +from google.ads.googleads.v12.enums.types import criterion_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignCriterion",}, +) + + +class CampaignCriterion(proto.Message): + r"""A campaign criterion. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign criterion. + Campaign criterion resource names have the form: + + ``customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}`` + campaign (str): + Immutable. The campaign to which the + criterion belongs. + + This field is a member of `oneof`_ ``_campaign``. + criterion_id (int): + Output only. The ID of the criterion. + This field is ignored during mutate. + + This field is a member of `oneof`_ ``_criterion_id``. + display_name (str): + Output only. The display name of the + criterion. + This field is ignored for mutates. + bid_modifier (float): + The modifier for the bids when the criterion + matches. The modifier must be in the range: 0.1 + - 10.0. Most targetable criteria types support + modifiers. Use 0 to opt out of a Device type. + + This field is a member of `oneof`_ ``_bid_modifier``. + negative (bool): + Immutable. Whether to target (``false``) or exclude + (``true``) the criterion. + + This field is a member of `oneof`_ ``_negative``. + type_ (google.ads.googleads.v12.enums.types.CriterionTypeEnum.CriterionType): + Output only. The type of the criterion. + status (google.ads.googleads.v12.enums.types.CampaignCriterionStatusEnum.CampaignCriterionStatus): + The status of the criterion. + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Immutable. Keyword. + + This field is a member of `oneof`_ ``criterion``. + placement (google.ads.googleads.v12.common.types.PlacementInfo): + Immutable. Placement. + + This field is a member of `oneof`_ ``criterion``. + mobile_app_category (google.ads.googleads.v12.common.types.MobileAppCategoryInfo): + Immutable. Mobile app category. + + This field is a member of `oneof`_ ``criterion``. + mobile_application (google.ads.googleads.v12.common.types.MobileApplicationInfo): + Immutable. Mobile application. + + This field is a member of `oneof`_ ``criterion``. + location (google.ads.googleads.v12.common.types.LocationInfo): + Immutable. Location. + + This field is a member of `oneof`_ ``criterion``. + device (google.ads.googleads.v12.common.types.DeviceInfo): + Immutable. Device. + + This field is a member of `oneof`_ ``criterion``. + ad_schedule (google.ads.googleads.v12.common.types.AdScheduleInfo): + Immutable. Ad Schedule. + + This field is a member of `oneof`_ ``criterion``. + age_range (google.ads.googleads.v12.common.types.AgeRangeInfo): + Immutable. Age range. + + This field is a member of `oneof`_ ``criterion``. + gender (google.ads.googleads.v12.common.types.GenderInfo): + Immutable. Gender. + + This field is a member of `oneof`_ ``criterion``. + income_range (google.ads.googleads.v12.common.types.IncomeRangeInfo): + Immutable. Income range. + + This field is a member of `oneof`_ ``criterion``. + parental_status (google.ads.googleads.v12.common.types.ParentalStatusInfo): + Immutable. Parental status. + + This field is a member of `oneof`_ ``criterion``. + user_list (google.ads.googleads.v12.common.types.UserListInfo): + Immutable. User List. + + This field is a member of `oneof`_ ``criterion``. + youtube_video (google.ads.googleads.v12.common.types.YouTubeVideoInfo): + Immutable. YouTube Video. + + This field is a member of `oneof`_ ``criterion``. + youtube_channel (google.ads.googleads.v12.common.types.YouTubeChannelInfo): + Immutable. YouTube Channel. + + This field is a member of `oneof`_ ``criterion``. + proximity (google.ads.googleads.v12.common.types.ProximityInfo): + Immutable. Proximity. + + This field is a member of `oneof`_ ``criterion``. + topic (google.ads.googleads.v12.common.types.TopicInfo): + Immutable. Topic. + + This field is a member of `oneof`_ ``criterion``. + listing_scope (google.ads.googleads.v12.common.types.ListingScopeInfo): + Immutable. Listing scope. + + This field is a member of `oneof`_ ``criterion``. + language (google.ads.googleads.v12.common.types.LanguageInfo): + Immutable. Language. + + This field is a member of `oneof`_ ``criterion``. + ip_block (google.ads.googleads.v12.common.types.IpBlockInfo): + Immutable. IpBlock. + + This field is a member of `oneof`_ ``criterion``. + content_label (google.ads.googleads.v12.common.types.ContentLabelInfo): + Immutable. ContentLabel. + + This field is a member of `oneof`_ ``criterion``. + carrier (google.ads.googleads.v12.common.types.CarrierInfo): + Immutable. Carrier. + + This field is a member of `oneof`_ ``criterion``. + user_interest (google.ads.googleads.v12.common.types.UserInterestInfo): + Immutable. User Interest. + + This field is a member of `oneof`_ ``criterion``. + webpage (google.ads.googleads.v12.common.types.WebpageInfo): + Immutable. Webpage. + + This field is a member of `oneof`_ ``criterion``. + operating_system_version (google.ads.googleads.v12.common.types.OperatingSystemVersionInfo): + Immutable. Operating system version. + + This field is a member of `oneof`_ ``criterion``. + mobile_device (google.ads.googleads.v12.common.types.MobileDeviceInfo): + Immutable. Mobile Device. + + This field is a member of `oneof`_ ``criterion``. + location_group (google.ads.googleads.v12.common.types.LocationGroupInfo): + Immutable. Location Group + + This field is a member of `oneof`_ ``criterion``. + custom_affinity (google.ads.googleads.v12.common.types.CustomAffinityInfo): + Immutable. Custom Affinity. + + This field is a member of `oneof`_ ``criterion``. + custom_audience (google.ads.googleads.v12.common.types.CustomAudienceInfo): + Immutable. Custom Audience + + This field is a member of `oneof`_ ``criterion``. + combined_audience (google.ads.googleads.v12.common.types.CombinedAudienceInfo): + Immutable. Combined Audience. + + This field is a member of `oneof`_ ``criterion``. + keyword_theme (google.ads.googleads.v12.common.types.KeywordThemeInfo): + Immutable. Smart Campaign Keyword Theme. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=37, optional=True,) + criterion_id = proto.Field(proto.INT64, number=38, optional=True,) + display_name = proto.Field(proto.STRING, number=43,) + bid_modifier = proto.Field(proto.FLOAT, number=39, optional=True,) + negative = proto.Field(proto.BOOL, number=40, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=6, + enum=criterion_type.CriterionTypeEnum.CriterionType, + ) + status = proto.Field( + proto.ENUM, + number=35, + enum=campaign_criterion_status.CampaignCriterionStatusEnum.CampaignCriterionStatus, + ) + keyword = proto.Field( + proto.MESSAGE, + number=8, + oneof="criterion", + message=criteria.KeywordInfo, + ) + placement = proto.Field( + proto.MESSAGE, + number=9, + oneof="criterion", + message=criteria.PlacementInfo, + ) + mobile_app_category = proto.Field( + proto.MESSAGE, + number=10, + oneof="criterion", + message=criteria.MobileAppCategoryInfo, + ) + mobile_application = proto.Field( + proto.MESSAGE, + number=11, + oneof="criterion", + message=criteria.MobileApplicationInfo, + ) + location = proto.Field( + proto.MESSAGE, + number=12, + oneof="criterion", + message=criteria.LocationInfo, + ) + device = proto.Field( + proto.MESSAGE, + number=13, + oneof="criterion", + message=criteria.DeviceInfo, + ) + ad_schedule = proto.Field( + proto.MESSAGE, + number=15, + oneof="criterion", + message=criteria.AdScheduleInfo, + ) + age_range = proto.Field( + proto.MESSAGE, + number=16, + oneof="criterion", + message=criteria.AgeRangeInfo, + ) + gender = proto.Field( + proto.MESSAGE, + number=17, + oneof="criterion", + message=criteria.GenderInfo, + ) + income_range = proto.Field( + proto.MESSAGE, + number=18, + oneof="criterion", + message=criteria.IncomeRangeInfo, + ) + parental_status = proto.Field( + proto.MESSAGE, + number=19, + oneof="criterion", + message=criteria.ParentalStatusInfo, + ) + user_list = proto.Field( + proto.MESSAGE, + number=22, + oneof="criterion", + message=criteria.UserListInfo, + ) + youtube_video = proto.Field( + proto.MESSAGE, + number=20, + oneof="criterion", + message=criteria.YouTubeVideoInfo, + ) + youtube_channel = proto.Field( + proto.MESSAGE, + number=21, + oneof="criterion", + message=criteria.YouTubeChannelInfo, + ) + proximity = proto.Field( + proto.MESSAGE, + number=23, + oneof="criterion", + message=criteria.ProximityInfo, + ) + topic = proto.Field( + proto.MESSAGE, number=24, oneof="criterion", message=criteria.TopicInfo, + ) + listing_scope = proto.Field( + proto.MESSAGE, + number=25, + oneof="criterion", + message=criteria.ListingScopeInfo, + ) + language = proto.Field( + proto.MESSAGE, + number=26, + oneof="criterion", + message=criteria.LanguageInfo, + ) + ip_block = proto.Field( + proto.MESSAGE, + number=27, + oneof="criterion", + message=criteria.IpBlockInfo, + ) + content_label = proto.Field( + proto.MESSAGE, + number=28, + oneof="criterion", + message=criteria.ContentLabelInfo, + ) + carrier = proto.Field( + proto.MESSAGE, + number=29, + oneof="criterion", + message=criteria.CarrierInfo, + ) + user_interest = proto.Field( + proto.MESSAGE, + number=30, + oneof="criterion", + message=criteria.UserInterestInfo, + ) + webpage = proto.Field( + proto.MESSAGE, + number=31, + oneof="criterion", + message=criteria.WebpageInfo, + ) + operating_system_version = proto.Field( + proto.MESSAGE, + number=32, + oneof="criterion", + message=criteria.OperatingSystemVersionInfo, + ) + mobile_device = proto.Field( + proto.MESSAGE, + number=33, + oneof="criterion", + message=criteria.MobileDeviceInfo, + ) + location_group = proto.Field( + proto.MESSAGE, + number=34, + oneof="criterion", + message=criteria.LocationGroupInfo, + ) + custom_affinity = proto.Field( + proto.MESSAGE, + number=36, + oneof="criterion", + message=criteria.CustomAffinityInfo, + ) + custom_audience = proto.Field( + proto.MESSAGE, + number=41, + oneof="criterion", + message=criteria.CustomAudienceInfo, + ) + combined_audience = proto.Field( + proto.MESSAGE, + number=42, + oneof="criterion", + message=criteria.CombinedAudienceInfo, + ) + keyword_theme = proto.Field( + proto.MESSAGE, + number=45, + oneof="criterion", + message=criteria.KeywordThemeInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_criterion_simulation.py b/google/ads/googleads/v12/resources/types/campaign_criterion_simulation.py new file mode 100644 index 000000000..3d7e95e68 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_criterion_simulation.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import simulation +from google.ads.googleads.v12.enums.types import simulation_modification_method +from google.ads.googleads.v12.enums.types import simulation_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignCriterionSimulation",}, +) + + +class CampaignCriterionSimulation(proto.Message): + r"""A campaign criterion simulation. Supported combinations of + advertising channel type, criterion ids, simulation type and + simulation modification method is detailed below respectively. + + 1. SEARCH - 30000,30001,30002 - BID_MODIFIER - UNIFORM + 2. DISPLAY - 30001 - BID_MODIFIER - UNIFORM + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the campaign criterion + simulation. Campaign criterion simulation resource names + have the form: + + ``customers/{customer_id}/campaignCriterionSimulations/{campaign_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}`` + campaign_id (int): + Output only. Campaign ID of the simulation. + + This field is a member of `oneof`_ ``_campaign_id``. + criterion_id (int): + Output only. Criterion ID of the simulation. + + This field is a member of `oneof`_ ``_criterion_id``. + type_ (google.ads.googleads.v12.enums.types.SimulationTypeEnum.SimulationType): + Output only. The field that the simulation + modifies. + modification_method (google.ads.googleads.v12.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + Output only. How the simulation modifies the + field. + start_date (str): + Output only. First day on which the + simulation is based, in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_start_date``. + end_date (str): + Output only. Last day on which the simulation + is based, in YYYY-MM-DD format. + + This field is a member of `oneof`_ ``_end_date``. + bid_modifier_point_list (google.ads.googleads.v12.common.types.BidModifierSimulationPointList): + Output only. Simulation points if the simulation type is + BID_MODIFIER. + + This field is a member of `oneof`_ ``point_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_id = proto.Field(proto.INT64, number=9, optional=True,) + criterion_id = proto.Field(proto.INT64, number=10, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=simulation_type.SimulationTypeEnum.SimulationType, + ) + modification_method = proto.Field( + proto.ENUM, + number=5, + enum=simulation_modification_method.SimulationModificationMethodEnum.SimulationModificationMethod, + ) + start_date = proto.Field(proto.STRING, number=11, optional=True,) + end_date = proto.Field(proto.STRING, number=12, optional=True,) + bid_modifier_point_list = proto.Field( + proto.MESSAGE, + number=8, + oneof="point_list", + message=simulation.BidModifierSimulationPointList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_customizer.py b/google/ads/googleads/v12/resources/types/campaign_customizer.py new file mode 100644 index 000000000..d0e71e330 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_customizer.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import customizer_value +from google.ads.googleads.v12.enums.types import customizer_value_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignCustomizer",}, +) + + +class CampaignCustomizer(proto.Message): + r"""A customizer value for the associated CustomizerAttribute at + the Campaign level. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign customizer. + Campaign customizer resource names have the form: + + ``customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}`` + campaign (str): + Immutable. The campaign to which the + customizer attribute is linked. + customizer_attribute (str): + Required. Immutable. The customizer attribute + which is linked to the campaign. + status (google.ads.googleads.v12.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + Output only. The status of the campaign + customizer. + value (google.ads.googleads.v12.common.types.CustomizerValue): + Required. The value to associate with the + customizer attribute at this level. The value + must be of the type specified for the + CustomizerAttribute. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + customizer_attribute = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=customizer_value_status.CustomizerValueStatusEnum.CustomizerValueStatus, + ) + value = proto.Field( + proto.MESSAGE, number=5, message=customizer_value.CustomizerValue, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_draft.py b/google/ads/googleads/v12/resources/types/campaign_draft.py new file mode 100644 index 000000000..93a4944a0 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_draft.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import campaign_draft_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignDraft",}, +) + + +class CampaignDraft(proto.Message): + r"""A campaign draft. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign draft. Campaign + draft resource names have the form: + + ``customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}`` + draft_id (int): + Output only. The ID of the draft. + This field is read-only. + + This field is a member of `oneof`_ ``_draft_id``. + base_campaign (str): + Immutable. The base campaign to which the + draft belongs. + + This field is a member of `oneof`_ ``_base_campaign``. + name (str): + The name of the campaign draft. + This field is required and should not be empty + when creating new campaign drafts. + + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + + This field is a member of `oneof`_ ``_name``. + draft_campaign (str): + Output only. Resource name of the Campaign + that results from overlaying the draft changes + onto the base campaign. + This field is read-only. + + This field is a member of `oneof`_ ``_draft_campaign``. + status (google.ads.googleads.v12.enums.types.CampaignDraftStatusEnum.CampaignDraftStatus): + Output only. The status of the campaign + draft. This field is read-only. + When a new campaign draft is added, the status + defaults to PROPOSED. + has_experiment_running (bool): + Output only. Whether there is an experiment + based on this draft currently serving. + + This field is a member of `oneof`_ ``_has_experiment_running``. + long_running_operation (str): + Output only. The resource name of the + long-running operation that can be used to poll + for completion of draft promotion. This is only + set if the draft promotion is in progress or + finished. + + This field is a member of `oneof`_ ``_long_running_operation``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + draft_id = proto.Field(proto.INT64, number=9, optional=True,) + base_campaign = proto.Field(proto.STRING, number=10, optional=True,) + name = proto.Field(proto.STRING, number=11, optional=True,) + draft_campaign = proto.Field(proto.STRING, number=12, optional=True,) + status = proto.Field( + proto.ENUM, + number=6, + enum=campaign_draft_status.CampaignDraftStatusEnum.CampaignDraftStatus, + ) + has_experiment_running = proto.Field(proto.BOOL, number=13, optional=True,) + long_running_operation = proto.Field( + proto.STRING, number=14, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_extension_setting.py b/google/ads/googleads/v12/resources/types/campaign_extension_setting.py new file mode 100644 index 000000000..2e6764658 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_extension_setting.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import extension_setting_device +from google.ads.googleads.v12.enums.types import ( + extension_type as gage_extension_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignExtensionSetting",}, +) + + +class CampaignExtensionSetting(proto.Message): + r"""A campaign extension setting. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign extension + setting. CampaignExtensionSetting resource names have the + form: + + ``customers/{customer_id}/campaignExtensionSettings/{campaign_id}~{extension_type}`` + extension_type (google.ads.googleads.v12.enums.types.ExtensionTypeEnum.ExtensionType): + Immutable. The extension type of the customer + extension setting. + campaign (str): + Immutable. The resource name of the campaign. The linked + extension feed items will serve under this campaign. + Campaign resource names have the form: + + ``customers/{customer_id}/campaigns/{campaign_id}`` + + This field is a member of `oneof`_ ``_campaign``. + extension_feed_items (Sequence[str]): + The resource names of the extension feed items to serve + under the campaign. ExtensionFeedItem resource names have + the form: + + ``customers/{customer_id}/extensionFeedItems/{feed_item_id}`` + device (google.ads.googleads.v12.enums.types.ExtensionSettingDeviceEnum.ExtensionSettingDevice): + The device for which the extensions will + serve. Optional. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + extension_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_extension_type.ExtensionTypeEnum.ExtensionType, + ) + campaign = proto.Field(proto.STRING, number=6, optional=True,) + extension_feed_items = proto.RepeatedField(proto.STRING, number=7,) + device = proto.Field( + proto.ENUM, + number=5, + enum=extension_setting_device.ExtensionSettingDeviceEnum.ExtensionSettingDevice, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_feed.py b/google/ads/googleads/v12/resources/types/campaign_feed.py new file mode 100644 index 000000000..c51d67607 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_feed.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + matching_function as gagc_matching_function, +) +from google.ads.googleads.v12.enums.types import feed_link_status +from google.ads.googleads.v12.enums.types import placeholder_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignFeed",}, +) + + +class CampaignFeed(proto.Message): + r"""A campaign feed. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign feed. Campaign + feed resource names have the form: + + \`customers/{customer_id}/campaignFeeds/{campaign_id}~{feed_id} + feed (str): + Immutable. The feed to which the CampaignFeed + belongs. + + This field is a member of `oneof`_ ``_feed``. + campaign (str): + Immutable. The campaign to which the + CampaignFeed belongs. + + This field is a member of `oneof`_ ``_campaign``. + placeholder_types (Sequence[google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType]): + Indicates which placeholder types the feed + may populate under the connected campaign. + Required. + matching_function (google.ads.googleads.v12.common.types.MatchingFunction): + Matching function associated with the + CampaignFeed. The matching function is used to + filter the set of feed items selected. Required. + status (google.ads.googleads.v12.enums.types.FeedLinkStatusEnum.FeedLinkStatus): + Output only. Status of the campaign feed. + This field is read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=7, optional=True,) + campaign = proto.Field(proto.STRING, number=8, optional=True,) + placeholder_types = proto.RepeatedField( + proto.ENUM, + number=4, + enum=placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + matching_function = proto.Field( + proto.MESSAGE, + number=5, + message=gagc_matching_function.MatchingFunction, + ) + status = proto.Field( + proto.ENUM, + number=6, + enum=feed_link_status.FeedLinkStatusEnum.FeedLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_group.py b/google/ads/googleads/v12/resources/types/campaign_group.py new file mode 100644 index 000000000..05b3d75af --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_group.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import campaign_group_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignGroup",}, +) + + +class CampaignGroup(proto.Message): + r"""A campaign group. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign group. Campaign + group resource names have the form: + + ``customers/{customer_id}/campaignGroups/{campaign_group_id}`` + id (int): + Output only. The ID of the campaign group. + name (str): + The name of the campaign group. + This field is required and should not be empty + when creating new campaign groups. + + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + status (google.ads.googleads.v12.enums.types.CampaignGroupStatusEnum.CampaignGroupStatus): + The status of the campaign group. + When a new campaign group is added, the status + defaults to ENABLED. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=3,) + name = proto.Field(proto.STRING, number=4,) + status = proto.Field( + proto.ENUM, + number=5, + enum=campaign_group_status.CampaignGroupStatusEnum.CampaignGroupStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_label.py b/google/ads/googleads/v12/resources/types/campaign_label.py new file mode 100644 index 000000000..12490da3c --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_label.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignLabel",}, +) + + +class CampaignLabel(proto.Message): + r"""Represents a relationship between a campaign and a label. + + Attributes: + resource_name (str): + Immutable. Name of the resource. Campaign label resource + names have the form: + ``customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}`` + campaign (str): + Immutable. The campaign to which the label is + attached. + + This field is a member of `oneof`_ ``_campaign``. + label (str): + Immutable. The label assigned to the + campaign. + + This field is a member of `oneof`_ ``_label``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=4, optional=True,) + label = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_shared_set.py b/google/ads/googleads/v12/resources/types/campaign_shared_set.py new file mode 100644 index 000000000..5edf0101e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_shared_set.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import campaign_shared_set_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignSharedSet",}, +) + + +class CampaignSharedSet(proto.Message): + r"""CampaignSharedSets are used for managing the shared sets + associated with a campaign. + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign shared set. + Campaign shared set resource names have the form: + + ``customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}`` + campaign (str): + Immutable. The campaign to which the campaign + shared set belongs. + + This field is a member of `oneof`_ ``_campaign``. + shared_set (str): + Immutable. The shared set associated with the + campaign. This may be a negative keyword shared + set of another customer. This customer should be + a manager of the other customer, otherwise the + campaign shared set will exist but have no + serving effect. Only negative keyword shared + sets can be associated with Shopping campaigns. + Only negative placement shared sets can be + associated with Display mobile app campaigns. + + This field is a member of `oneof`_ ``_shared_set``. + status (google.ads.googleads.v12.enums.types.CampaignSharedSetStatusEnum.CampaignSharedSetStatus): + Output only. The status of this campaign + shared set. Read only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=5, optional=True,) + shared_set = proto.Field(proto.STRING, number=6, optional=True,) + status = proto.Field( + proto.ENUM, + number=2, + enum=campaign_shared_set_status.CampaignSharedSetStatusEnum.CampaignSharedSetStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/campaign_simulation.py b/google/ads/googleads/v12/resources/types/campaign_simulation.py new file mode 100644 index 000000000..cd7e6e5a2 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/campaign_simulation.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import simulation +from google.ads.googleads.v12.enums.types import simulation_modification_method +from google.ads.googleads.v12.enums.types import simulation_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CampaignSimulation",}, +) + + +class CampaignSimulation(proto.Message): + r"""A campaign simulation. Supported combinations of advertising channel + type, simulation type and simulation modification method is detailed + below respectively. + + - SEARCH - CPC_BID - UNIFORM + - SEARCH - CPC_BID - SCALING + - SEARCH - TARGET_CPA - UNIFORM + - SEARCH - TARGET_CPA - SCALING + - SEARCH - TARGET_ROAS - UNIFORM + - SEARCH - TARGET_IMPRESSION_SHARE - UNIFORM + - SEARCH - BUDGET - UNIFORM + - SHOPPING - BUDGET - UNIFORM + - SHOPPING - TARGET_ROAS - UNIFORM + - MULTI_CHANNEL - TARGET_CPA - UNIFORM + - DISCOVERY - TARGET_CPA - DEFAULT + - DISPLAY - TARGET_CPA - UNIFORM + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the campaign simulation. + Campaign simulation resource names have the form: + + ``customers/{customer_id}/campaignSimulations/{campaign_id}~{type}~{modification_method}~{start_date}~{end_date}`` + campaign_id (int): + Output only. Campaign id of the simulation. + type_ (google.ads.googleads.v12.enums.types.SimulationTypeEnum.SimulationType): + Output only. The field that the simulation + modifies. + modification_method (google.ads.googleads.v12.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + Output only. How the simulation modifies the + field. + start_date (str): + Output only. First day on which the + simulation is based, in YYYY-MM-DD format. + end_date (str): + Output only. Last day on which the simulation + is based, in YYYY-MM-DD format + cpc_bid_point_list (google.ads.googleads.v12.common.types.CpcBidSimulationPointList): + Output only. Simulation points if the simulation type is + CPC_BID. + + This field is a member of `oneof`_ ``point_list``. + target_cpa_point_list (google.ads.googleads.v12.common.types.TargetCpaSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_CPA. + + This field is a member of `oneof`_ ``point_list``. + target_roas_point_list (google.ads.googleads.v12.common.types.TargetRoasSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_ROAS. + + This field is a member of `oneof`_ ``point_list``. + target_impression_share_point_list (google.ads.googleads.v12.common.types.TargetImpressionShareSimulationPointList): + Output only. Simulation points if the simulation type is + TARGET_IMPRESSION_SHARE. + + This field is a member of `oneof`_ ``point_list``. + budget_point_list (google.ads.googleads.v12.common.types.BudgetSimulationPointList): + Output only. Simulation points if the + simulation type is BUDGET. + + This field is a member of `oneof`_ ``point_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_id = proto.Field(proto.INT64, number=2,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=simulation_type.SimulationTypeEnum.SimulationType, + ) + modification_method = proto.Field( + proto.ENUM, + number=4, + enum=simulation_modification_method.SimulationModificationMethodEnum.SimulationModificationMethod, + ) + start_date = proto.Field(proto.STRING, number=5,) + end_date = proto.Field(proto.STRING, number=6,) + cpc_bid_point_list = proto.Field( + proto.MESSAGE, + number=7, + oneof="point_list", + message=simulation.CpcBidSimulationPointList, + ) + target_cpa_point_list = proto.Field( + proto.MESSAGE, + number=8, + oneof="point_list", + message=simulation.TargetCpaSimulationPointList, + ) + target_roas_point_list = proto.Field( + proto.MESSAGE, + number=9, + oneof="point_list", + message=simulation.TargetRoasSimulationPointList, + ) + target_impression_share_point_list = proto.Field( + proto.MESSAGE, + number=10, + oneof="point_list", + message=simulation.TargetImpressionShareSimulationPointList, + ) + budget_point_list = proto.Field( + proto.MESSAGE, + number=11, + oneof="point_list", + message=simulation.BudgetSimulationPointList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/carrier_constant.py b/google/ads/googleads/v12/resources/types/carrier_constant.py new file mode 100644 index 000000000..35c75a68f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/carrier_constant.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CarrierConstant",}, +) + + +class CarrierConstant(proto.Message): + r"""A carrier criterion that can be used in campaign targeting. + + Attributes: + resource_name (str): + Output only. The resource name of the carrier criterion. + Carrier criterion resource names have the form: + + ``carrierConstants/{criterion_id}`` + id (int): + Output only. The ID of the carrier criterion. + + This field is a member of `oneof`_ ``_id``. + name (str): + Output only. The full name of the carrier in + English. + + This field is a member of `oneof`_ ``_name``. + country_code (str): + Output only. The country code of the country + where the carrier is located, for example, "AR", + "FR", etc. + + This field is a member of `oneof`_ ``_country_code``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=5, optional=True,) + name = proto.Field(proto.STRING, number=6, optional=True,) + country_code = proto.Field(proto.STRING, number=7, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/change_event.py b/google/ads/googleads/v12/resources/types/change_event.py new file mode 100644 index 000000000..25dd3eb06 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/change_event.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import change_client_type +from google.ads.googleads.v12.enums.types import change_event_resource_type +from google.ads.googleads.v12.enums.types import ( + resource_change_operation as gage_resource_change_operation, +) +from google.ads.googleads.v12.resources.types import ad as gagr_ad +from google.ads.googleads.v12.resources.types import ad_group as gagr_ad_group +from google.ads.googleads.v12.resources.types import ( + ad_group_ad as gagr_ad_group_ad, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_asset as gagr_ad_group_asset, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_bid_modifier as gagr_ad_group_bid_modifier, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion as gagr_ad_group_criterion, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_feed as gagr_ad_group_feed, +) +from google.ads.googleads.v12.resources.types import asset as gagr_asset +from google.ads.googleads.v12.resources.types import asset_set as gagr_asset_set +from google.ads.googleads.v12.resources.types import ( + asset_set_asset as gagr_asset_set_asset, +) +from google.ads.googleads.v12.resources.types import campaign as gagr_campaign +from google.ads.googleads.v12.resources.types import ( + campaign_asset as gagr_campaign_asset, +) +from google.ads.googleads.v12.resources.types import ( + campaign_asset_set as gagr_campaign_asset_set, +) +from google.ads.googleads.v12.resources.types import ( + campaign_budget as gagr_campaign_budget, +) +from google.ads.googleads.v12.resources.types import ( + campaign_criterion as gagr_campaign_criterion, +) +from google.ads.googleads.v12.resources.types import ( + campaign_feed as gagr_campaign_feed, +) +from google.ads.googleads.v12.resources.types import ( + customer_asset as gagr_customer_asset, +) +from google.ads.googleads.v12.resources.types import feed as gagr_feed +from google.ads.googleads.v12.resources.types import feed_item as gagr_feed_item +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ChangeEvent",}, +) + + +class ChangeEvent(proto.Message): + r"""Describes the granular change of returned resource of certain + resource types. Changes made through UI, API and new versions of + Editor by external users (including external users, and internal + users that can be shown externally) in the past 30 days will be + shown. The change shows the old values of the changed fields + before the change and the new values right after the change. + ChangeEvent could have up to 3 minutes delay to reflect a new + change. + + Attributes: + resource_name (str): + Output only. The resource name of the change event. Change + event resource names have the form: + + ``customers/{customer_id}/changeEvents/{timestamp_micros}~{command_index}~{mutate_index}`` + change_date_time (str): + Output only. Time at which the change was + committed on this resource. + change_resource_type (google.ads.googleads.v12.enums.types.ChangeEventResourceTypeEnum.ChangeEventResourceType): + Output only. The type of the changed resource. This dictates + what resource will be set in old_resource and new_resource. + change_resource_name (str): + Output only. The Simply resource this change + occurred on. + client_type (google.ads.googleads.v12.enums.types.ChangeClientTypeEnum.ChangeClientType): + Output only. Where the change was made + through. + user_email (str): + Output only. The email of the user who made + this change. + old_resource (google.ads.googleads.v12.resources.types.ChangeEvent.ChangedResource): + Output only. The old resource before the + change. Only changed fields will be populated. + new_resource (google.ads.googleads.v12.resources.types.ChangeEvent.ChangedResource): + Output only. The new resource after the + change. Only changed fields will be populated. + resource_change_operation (google.ads.googleads.v12.enums.types.ResourceChangeOperationEnum.ResourceChangeOperation): + Output only. The operation on the changed + resource. + changed_fields (google.protobuf.field_mask_pb2.FieldMask): + Output only. A list of fields that are + changed in the returned resource. + campaign (str): + Output only. The Campaign affected by this + change. + ad_group (str): + Output only. The AdGroup affected by this + change. + feed (str): + Output only. The Feed affected by this + change. + feed_item (str): + Output only. The FeedItem affected by this + change. + asset (str): + Output only. The Asset affected by this + change. + """ + + class ChangedResource(proto.Message): + r"""A wrapper proto presenting all supported resources. Only the + resource of the change_resource_type will be set. + + Attributes: + ad (google.ads.googleads.v12.resources.types.Ad): + Output only. Set if change_resource_type == AD. + ad_group (google.ads.googleads.v12.resources.types.AdGroup): + Output only. Set if change_resource_type == AD_GROUP. + ad_group_criterion (google.ads.googleads.v12.resources.types.AdGroupCriterion): + Output only. Set if change_resource_type == + AD_GROUP_CRITERION. + campaign (google.ads.googleads.v12.resources.types.Campaign): + Output only. Set if change_resource_type == CAMPAIGN. + campaign_budget (google.ads.googleads.v12.resources.types.CampaignBudget): + Output only. Set if change_resource_type == CAMPAIGN_BUDGET. + ad_group_bid_modifier (google.ads.googleads.v12.resources.types.AdGroupBidModifier): + Output only. Set if change_resource_type == + AD_GROUP_BID_MODIFIER. + campaign_criterion (google.ads.googleads.v12.resources.types.CampaignCriterion): + Output only. Set if change_resource_type == + CAMPAIGN_CRITERION. + feed (google.ads.googleads.v12.resources.types.Feed): + Output only. Set if change_resource_type == FEED. + feed_item (google.ads.googleads.v12.resources.types.FeedItem): + Output only. Set if change_resource_type == FEED_ITEM. + campaign_feed (google.ads.googleads.v12.resources.types.CampaignFeed): + Output only. Set if change_resource_type == CAMPAIGN_FEED. + ad_group_feed (google.ads.googleads.v12.resources.types.AdGroupFeed): + Output only. Set if change_resource_type == AD_GROUP_FEED. + ad_group_ad (google.ads.googleads.v12.resources.types.AdGroupAd): + Output only. Set if change_resource_type == AD_GROUP_AD. + asset (google.ads.googleads.v12.resources.types.Asset): + Output only. Set if change_resource_type == ASSET. + customer_asset (google.ads.googleads.v12.resources.types.CustomerAsset): + Output only. Set if change_resource_type == CUSTOMER_ASSET. + campaign_asset (google.ads.googleads.v12.resources.types.CampaignAsset): + Output only. Set if change_resource_type == CAMPAIGN_ASSET. + ad_group_asset (google.ads.googleads.v12.resources.types.AdGroupAsset): + Output only. Set if change_resource_type == AD_GROUP_ASSET. + asset_set (google.ads.googleads.v12.resources.types.AssetSet): + Output only. Set if change_resource_type == ASSET_SET. + asset_set_asset (google.ads.googleads.v12.resources.types.AssetSetAsset): + Output only. Set if change_resource_type == ASSET_SET_ASSET. + campaign_asset_set (google.ads.googleads.v12.resources.types.CampaignAssetSet): + Output only. Set if change_resource_type == + CAMPAIGN_ASSET_SET. + """ + + ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + ad_group = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_group.AdGroup, + ) + ad_group_criterion = proto.Field( + proto.MESSAGE, + number=3, + message=gagr_ad_group_criterion.AdGroupCriterion, + ) + campaign = proto.Field( + proto.MESSAGE, number=4, message=gagr_campaign.Campaign, + ) + campaign_budget = proto.Field( + proto.MESSAGE, + number=5, + message=gagr_campaign_budget.CampaignBudget, + ) + ad_group_bid_modifier = proto.Field( + proto.MESSAGE, + number=6, + message=gagr_ad_group_bid_modifier.AdGroupBidModifier, + ) + campaign_criterion = proto.Field( + proto.MESSAGE, + number=7, + message=gagr_campaign_criterion.CampaignCriterion, + ) + feed = proto.Field(proto.MESSAGE, number=8, message=gagr_feed.Feed,) + feed_item = proto.Field( + proto.MESSAGE, number=9, message=gagr_feed_item.FeedItem, + ) + campaign_feed = proto.Field( + proto.MESSAGE, number=10, message=gagr_campaign_feed.CampaignFeed, + ) + ad_group_feed = proto.Field( + proto.MESSAGE, number=11, message=gagr_ad_group_feed.AdGroupFeed, + ) + ad_group_ad = proto.Field( + proto.MESSAGE, number=12, message=gagr_ad_group_ad.AdGroupAd, + ) + asset = proto.Field(proto.MESSAGE, number=13, message=gagr_asset.Asset,) + customer_asset = proto.Field( + proto.MESSAGE, number=14, message=gagr_customer_asset.CustomerAsset, + ) + campaign_asset = proto.Field( + proto.MESSAGE, number=15, message=gagr_campaign_asset.CampaignAsset, + ) + ad_group_asset = proto.Field( + proto.MESSAGE, number=16, message=gagr_ad_group_asset.AdGroupAsset, + ) + asset_set = proto.Field( + proto.MESSAGE, number=17, message=gagr_asset_set.AssetSet, + ) + asset_set_asset = proto.Field( + proto.MESSAGE, + number=18, + message=gagr_asset_set_asset.AssetSetAsset, + ) + campaign_asset_set = proto.Field( + proto.MESSAGE, + number=19, + message=gagr_campaign_asset_set.CampaignAssetSet, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + change_date_time = proto.Field(proto.STRING, number=2,) + change_resource_type = proto.Field( + proto.ENUM, + number=3, + enum=change_event_resource_type.ChangeEventResourceTypeEnum.ChangeEventResourceType, + ) + change_resource_name = proto.Field(proto.STRING, number=4,) + client_type = proto.Field( + proto.ENUM, + number=5, + enum=change_client_type.ChangeClientTypeEnum.ChangeClientType, + ) + user_email = proto.Field(proto.STRING, number=6,) + old_resource = proto.Field( + proto.MESSAGE, number=7, message=ChangedResource, + ) + new_resource = proto.Field( + proto.MESSAGE, number=8, message=ChangedResource, + ) + resource_change_operation = proto.Field( + proto.ENUM, + number=9, + enum=gage_resource_change_operation.ResourceChangeOperationEnum.ResourceChangeOperation, + ) + changed_fields = proto.Field( + proto.MESSAGE, number=10, message=field_mask_pb2.FieldMask, + ) + campaign = proto.Field(proto.STRING, number=11,) + ad_group = proto.Field(proto.STRING, number=12,) + feed = proto.Field(proto.STRING, number=13,) + feed_item = proto.Field(proto.STRING, number=14,) + asset = proto.Field(proto.STRING, number=20,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/change_status.py b/google/ads/googleads/v12/resources/types/change_status.py new file mode 100644 index 000000000..439b74a83 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/change_status.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import change_status_operation +from google.ads.googleads.v12.enums.types import change_status_resource_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ChangeStatus",}, +) + + +class ChangeStatus(proto.Message): + r"""Describes the status of returned resource. ChangeStatus could + have up to 3 minutes delay to reflect a new change. + + Attributes: + resource_name (str): + Output only. The resource name of the change status. Change + status resource names have the form: + + ``customers/{customer_id}/changeStatus/{change_status_id}`` + last_change_date_time (str): + Output only. Time at which the most recent + change has occurred on this resource. + + This field is a member of `oneof`_ ``_last_change_date_time``. + resource_type (google.ads.googleads.v12.enums.types.ChangeStatusResourceTypeEnum.ChangeStatusResourceType): + Output only. Represents the type of the changed resource. + This dictates what fields will be set. For example, for + AD_GROUP, campaign and ad_group fields will be set. + campaign (str): + Output only. The Campaign affected by this + change. + + This field is a member of `oneof`_ ``_campaign``. + ad_group (str): + Output only. The AdGroup affected by this + change. + + This field is a member of `oneof`_ ``_ad_group``. + resource_status (google.ads.googleads.v12.enums.types.ChangeStatusOperationEnum.ChangeStatusOperation): + Output only. Represents the status of the + changed resource. + ad_group_ad (str): + Output only. The AdGroupAd affected by this + change. + + This field is a member of `oneof`_ ``_ad_group_ad``. + ad_group_criterion (str): + Output only. The AdGroupCriterion affected by + this change. + + This field is a member of `oneof`_ ``_ad_group_criterion``. + campaign_criterion (str): + Output only. The CampaignCriterion affected + by this change. + + This field is a member of `oneof`_ ``_campaign_criterion``. + feed (str): + Output only. The Feed affected by this + change. + + This field is a member of `oneof`_ ``_feed``. + feed_item (str): + Output only. The FeedItem affected by this + change. + + This field is a member of `oneof`_ ``_feed_item``. + ad_group_feed (str): + Output only. The AdGroupFeed affected by this + change. + + This field is a member of `oneof`_ ``_ad_group_feed``. + campaign_feed (str): + Output only. The CampaignFeed affected by + this change. + + This field is a member of `oneof`_ ``_campaign_feed``. + ad_group_bid_modifier (str): + Output only. The AdGroupBidModifier affected + by this change. + + This field is a member of `oneof`_ ``_ad_group_bid_modifier``. + shared_set (str): + Output only. The SharedSet affected by this + change. + campaign_shared_set (str): + Output only. The CampaignSharedSet affected + by this change. + asset (str): + Output only. The Asset affected by this + change. + customer_asset (str): + Output only. The CustomerAsset affected by + this change. + campaign_asset (str): + Output only. The CampaignAsset affected by + this change. + ad_group_asset (str): + Output only. The AdGroupAsset affected by + this change. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + last_change_date_time = proto.Field(proto.STRING, number=24, optional=True,) + resource_type = proto.Field( + proto.ENUM, + number=4, + enum=change_status_resource_type.ChangeStatusResourceTypeEnum.ChangeStatusResourceType, + ) + campaign = proto.Field(proto.STRING, number=17, optional=True,) + ad_group = proto.Field(proto.STRING, number=18, optional=True,) + resource_status = proto.Field( + proto.ENUM, + number=8, + enum=change_status_operation.ChangeStatusOperationEnum.ChangeStatusOperation, + ) + ad_group_ad = proto.Field(proto.STRING, number=25, optional=True,) + ad_group_criterion = proto.Field(proto.STRING, number=26, optional=True,) + campaign_criterion = proto.Field(proto.STRING, number=27, optional=True,) + feed = proto.Field(proto.STRING, number=28, optional=True,) + feed_item = proto.Field(proto.STRING, number=29, optional=True,) + ad_group_feed = proto.Field(proto.STRING, number=30, optional=True,) + campaign_feed = proto.Field(proto.STRING, number=31, optional=True,) + ad_group_bid_modifier = proto.Field(proto.STRING, number=32, optional=True,) + shared_set = proto.Field(proto.STRING, number=33,) + campaign_shared_set = proto.Field(proto.STRING, number=34,) + asset = proto.Field(proto.STRING, number=35,) + customer_asset = proto.Field(proto.STRING, number=36,) + campaign_asset = proto.Field(proto.STRING, number=37,) + ad_group_asset = proto.Field(proto.STRING, number=38,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/click_view.py b/google/ads/googleads/v12/resources/types/click_view.py new file mode 100644 index 000000000..6a5dc765f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/click_view.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import click_location +from google.ads.googleads.v12.common.types import criteria + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ClickView",}, +) + + +class ClickView(proto.Message): + r"""A click view with metrics aggregated at each click level, + including both valid and invalid clicks. For non-Search + campaigns, metrics.clicks represents the number of valid and + invalid interactions. Queries including ClickView must have a + filter limiting the results to one day and can be requested for + dates back to 90 days before the time of the request. + + Attributes: + resource_name (str): + Output only. The resource name of the click view. Click view + resource names have the form: + + ``customers/{customer_id}/clickViews/{date (yyyy-MM-dd)}~{gclid}`` + gclid (str): + Output only. The Google Click ID. + + This field is a member of `oneof`_ ``_gclid``. + area_of_interest (google.ads.googleads.v12.common.types.ClickLocation): + Output only. The location criteria matching + the area of interest associated with the + impression. + location_of_presence (google.ads.googleads.v12.common.types.ClickLocation): + Output only. The location criteria matching + the location of presence associated with the + impression. + page_number (int): + Output only. Page number in search results + where the ad was shown. + + This field is a member of `oneof`_ ``_page_number``. + ad_group_ad (str): + Output only. The associated ad. + + This field is a member of `oneof`_ ``_ad_group_ad``. + campaign_location_target (str): + Output only. The associated campaign location + target, if one exists. + + This field is a member of `oneof`_ ``_campaign_location_target``. + user_list (str): + Output only. The associated user list, if one + exists. + + This field is a member of `oneof`_ ``_user_list``. + keyword (str): + Output only. The associated keyword, if one + exists and the click corresponds to the SEARCH + channel. + keyword_info (google.ads.googleads.v12.common.types.KeywordInfo): + Output only. Basic information about the + associated keyword, if it exists. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + gclid = proto.Field(proto.STRING, number=8, optional=True,) + area_of_interest = proto.Field( + proto.MESSAGE, number=3, message=click_location.ClickLocation, + ) + location_of_presence = proto.Field( + proto.MESSAGE, number=4, message=click_location.ClickLocation, + ) + page_number = proto.Field(proto.INT64, number=9, optional=True,) + ad_group_ad = proto.Field(proto.STRING, number=10, optional=True,) + campaign_location_target = proto.Field( + proto.STRING, number=11, optional=True, + ) + user_list = proto.Field(proto.STRING, number=12, optional=True,) + keyword = proto.Field(proto.STRING, number=13,) + keyword_info = proto.Field( + proto.MESSAGE, number=14, message=criteria.KeywordInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/combined_audience.py b/google/ads/googleads/v12/resources/types/combined_audience.py new file mode 100644 index 000000000..dcee29b99 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/combined_audience.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import combined_audience_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CombinedAudience",}, +) + + +class CombinedAudience(proto.Message): + r"""Describe a resource for combined audiences which includes + different audiences. + + Attributes: + resource_name (str): + Immutable. The resource name of the combined audience. + Combined audience names have the form: + + ``customers/{customer_id}/combinedAudience/{combined_audience_id}`` + id (int): + Output only. ID of the combined audience. + status (google.ads.googleads.v12.enums.types.CombinedAudienceStatusEnum.CombinedAudienceStatus): + Output only. Status of this combined + audience. Indicates whether the combined + audience is enabled or removed. + name (str): + Output only. Name of the combined audience. + It should be unique across all combined + audiences. + description (str): + Output only. Description of this combined + audience. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + status = proto.Field( + proto.ENUM, + number=3, + enum=combined_audience_status.CombinedAudienceStatusEnum.CombinedAudienceStatus, + ) + name = proto.Field(proto.STRING, number=4,) + description = proto.Field(proto.STRING, number=5,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/conversion_action.py b/google/ads/googleads/v12/resources/types/conversion_action.py new file mode 100644 index 000000000..f749a0eea --- /dev/null +++ b/google/ads/googleads/v12/resources/types/conversion_action.py @@ -0,0 +1,317 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import tag_snippet +from google.ads.googleads.v12.enums.types import ( + attribution_model as gage_attribution_model, +) +from google.ads.googleads.v12.enums.types import conversion_action_category +from google.ads.googleads.v12.enums.types import conversion_action_counting_type +from google.ads.googleads.v12.enums.types import conversion_action_status +from google.ads.googleads.v12.enums.types import conversion_action_type +from google.ads.googleads.v12.enums.types import conversion_origin +from google.ads.googleads.v12.enums.types import ( + data_driven_model_status as gage_data_driven_model_status, +) +from google.ads.googleads.v12.enums.types import ( + mobile_app_vendor as gage_mobile_app_vendor, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ConversionAction",}, +) + + +class ConversionAction(proto.Message): + r"""A conversion action. + + Attributes: + resource_name (str): + Immutable. The resource name of the conversion action. + Conversion action resource names have the form: + + ``customers/{customer_id}/conversionActions/{conversion_action_id}`` + id (int): + Output only. The ID of the conversion action. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the conversion action. + This field is required and should not be empty + when creating new conversion actions. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v12.enums.types.ConversionActionStatusEnum.ConversionActionStatus): + The status of this conversion action for + conversion event accrual. + type_ (google.ads.googleads.v12.enums.types.ConversionActionTypeEnum.ConversionActionType): + Immutable. The type of this conversion + action. + origin (google.ads.googleads.v12.enums.types.ConversionOriginEnum.ConversionOrigin): + Output only. The conversion origin of this + conversion action. + primary_for_goal (bool): + If a conversion action's primary_for_goal bit is false, the + conversion action is non-biddable for all campaigns + regardless of their customer conversion goal or campaign + conversion goal. However, custom conversion goals do not + respect primary_for_goal, so if a campaign has a custom + conversion goal configured with a primary_for_goal = false + conversion action, that conversion action is still biddable. + By default, primary_for_goal will be true if not set. In V9, + primary_for_goal can only be set to false after creation + through an 'update' operation because it's not declared as + optional. + + This field is a member of `oneof`_ ``_primary_for_goal``. + category (google.ads.googleads.v12.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + The category of conversions reported for this + conversion action. + owner_customer (str): + Output only. The resource name of the + conversion action owner customer, or null if + this is a system-defined conversion action. + + This field is a member of `oneof`_ ``_owner_customer``. + include_in_conversions_metric (bool): + Whether this conversion action should be + included in the "conversions" metric. + + This field is a member of `oneof`_ ``_include_in_conversions_metric``. + click_through_lookback_window_days (int): + The maximum number of days that may elapse + between an interaction (for example, a click) + and a conversion event. + + This field is a member of `oneof`_ ``_click_through_lookback_window_days``. + view_through_lookback_window_days (int): + The maximum number of days which may elapse + between an impression and a conversion without + an interaction. + + This field is a member of `oneof`_ ``_view_through_lookback_window_days``. + value_settings (google.ads.googleads.v12.resources.types.ConversionAction.ValueSettings): + Settings related to the value for conversion + events associated with this conversion action. + counting_type (google.ads.googleads.v12.enums.types.ConversionActionCountingTypeEnum.ConversionActionCountingType): + How to count conversion events for the + conversion action. + attribution_model_settings (google.ads.googleads.v12.resources.types.ConversionAction.AttributionModelSettings): + Settings related to this conversion action's + attribution model. + tag_snippets (Sequence[google.ads.googleads.v12.common.types.TagSnippet]): + Output only. The snippets used for tracking + conversions. + phone_call_duration_seconds (int): + The phone call duration in seconds after + which a conversion should be reported for this + conversion action. + The value must be between 0 and 10000, + inclusive. + + This field is a member of `oneof`_ ``_phone_call_duration_seconds``. + app_id (str): + App ID for an app conversion action. + + This field is a member of `oneof`_ ``_app_id``. + mobile_app_vendor (google.ads.googleads.v12.enums.types.MobileAppVendorEnum.MobileAppVendor): + Output only. Mobile app vendor for an app + conversion action. + firebase_settings (google.ads.googleads.v12.resources.types.ConversionAction.FirebaseSettings): + Output only. Firebase settings for Firebase + conversion types. + third_party_app_analytics_settings (google.ads.googleads.v12.resources.types.ConversionAction.ThirdPartyAppAnalyticsSettings): + Output only. Third Party App Analytics + settings for third party conversion types. + """ + + class AttributionModelSettings(proto.Message): + r"""Settings related to this conversion action's attribution + model. + + Attributes: + attribution_model (google.ads.googleads.v12.enums.types.AttributionModelEnum.AttributionModel): + The attribution model type of this conversion + action. + data_driven_model_status (google.ads.googleads.v12.enums.types.DataDrivenModelStatusEnum.DataDrivenModelStatus): + Output only. The status of the data-driven + attribution model for the conversion action. + """ + + attribution_model = proto.Field( + proto.ENUM, + number=1, + enum=gage_attribution_model.AttributionModelEnum.AttributionModel, + ) + data_driven_model_status = proto.Field( + proto.ENUM, + number=2, + enum=gage_data_driven_model_status.DataDrivenModelStatusEnum.DataDrivenModelStatus, + ) + + class ValueSettings(proto.Message): + r"""Settings related to the value for conversion events + associated with this conversion action. + + Attributes: + default_value (float): + The value to use when conversion events for + this conversion action are sent with an invalid, + disallowed or missing value, or when this + conversion action is configured to always use + the default value. + + This field is a member of `oneof`_ ``_default_value``. + default_currency_code (str): + The currency code to use when conversion + events for this conversion action are sent with + an invalid or missing currency code, or when + this conversion action is configured to always + use the default value. + + This field is a member of `oneof`_ ``_default_currency_code``. + always_use_default_value (bool): + Controls whether the default value and + default currency code are used in place of the + value and currency code specified in conversion + events for this conversion action. + + This field is a member of `oneof`_ ``_always_use_default_value``. + """ + + default_value = proto.Field(proto.DOUBLE, number=4, optional=True,) + default_currency_code = proto.Field( + proto.STRING, number=5, optional=True, + ) + always_use_default_value = proto.Field( + proto.BOOL, number=6, optional=True, + ) + + class ThirdPartyAppAnalyticsSettings(proto.Message): + r"""Settings related to a third party app analytics conversion + action. + + Attributes: + event_name (str): + Output only. The event name of a third-party + app analytics conversion. + + This field is a member of `oneof`_ ``_event_name``. + provider_name (str): + Output only. Name of the third-party app + analytics provider. + """ + + event_name = proto.Field(proto.STRING, number=2, optional=True,) + provider_name = proto.Field(proto.STRING, number=3,) + + class FirebaseSettings(proto.Message): + r"""Settings related to a Firebase conversion action. + + Attributes: + event_name (str): + Output only. The event name of a Firebase + conversion. + + This field is a member of `oneof`_ ``_event_name``. + project_id (str): + Output only. The Firebase project ID of the + conversion. + + This field is a member of `oneof`_ ``_project_id``. + property_id (int): + Output only. The GA property ID of the + conversion. + property_name (str): + Output only. The GA property name of the + conversion. + """ + + event_name = proto.Field(proto.STRING, number=3, optional=True,) + project_id = proto.Field(proto.STRING, number=4, optional=True,) + property_id = proto.Field(proto.INT64, number=5,) + property_name = proto.Field(proto.STRING, number=6,) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=21, optional=True,) + name = proto.Field(proto.STRING, number=22, optional=True,) + status = proto.Field( + proto.ENUM, + number=4, + enum=conversion_action_status.ConversionActionStatusEnum.ConversionActionStatus, + ) + type_ = proto.Field( + proto.ENUM, + number=5, + enum=conversion_action_type.ConversionActionTypeEnum.ConversionActionType, + ) + origin = proto.Field( + proto.ENUM, + number=30, + enum=conversion_origin.ConversionOriginEnum.ConversionOrigin, + ) + primary_for_goal = proto.Field(proto.BOOL, number=31, optional=True,) + category = proto.Field( + proto.ENUM, + number=6, + enum=conversion_action_category.ConversionActionCategoryEnum.ConversionActionCategory, + ) + owner_customer = proto.Field(proto.STRING, number=23, optional=True,) + include_in_conversions_metric = proto.Field( + proto.BOOL, number=24, optional=True, + ) + click_through_lookback_window_days = proto.Field( + proto.INT64, number=25, optional=True, + ) + view_through_lookback_window_days = proto.Field( + proto.INT64, number=26, optional=True, + ) + value_settings = proto.Field( + proto.MESSAGE, number=11, message=ValueSettings, + ) + counting_type = proto.Field( + proto.ENUM, + number=12, + enum=conversion_action_counting_type.ConversionActionCountingTypeEnum.ConversionActionCountingType, + ) + attribution_model_settings = proto.Field( + proto.MESSAGE, number=13, message=AttributionModelSettings, + ) + tag_snippets = proto.RepeatedField( + proto.MESSAGE, number=14, message=tag_snippet.TagSnippet, + ) + phone_call_duration_seconds = proto.Field( + proto.INT64, number=27, optional=True, + ) + app_id = proto.Field(proto.STRING, number=28, optional=True,) + mobile_app_vendor = proto.Field( + proto.ENUM, + number=17, + enum=gage_mobile_app_vendor.MobileAppVendorEnum.MobileAppVendor, + ) + firebase_settings = proto.Field( + proto.MESSAGE, number=18, message=FirebaseSettings, + ) + third_party_app_analytics_settings = proto.Field( + proto.MESSAGE, number=19, message=ThirdPartyAppAnalyticsSettings, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/conversion_custom_variable.py b/google/ads/googleads/v12/resources/types/conversion_custom_variable.py new file mode 100644 index 000000000..f37c7ed29 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/conversion_custom_variable.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + conversion_custom_variable_status, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ConversionCustomVariable",}, +) + + +class ConversionCustomVariable(proto.Message): + r"""A conversion custom variable + See "About custom variables for conversions" at + https://support.google.com/google-ads/answer/9964350 + + Attributes: + resource_name (str): + Immutable. The resource name of the conversion custom + variable. Conversion custom variable resource names have the + form: + + ``customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}`` + id (int): + Output only. The ID of the conversion custom + variable. + name (str): + Required. The name of the conversion custom + variable. Name should be unique. The maximum + length of name is 100 characters. There should + not be any extra spaces before and after. + tag (str): + Required. Immutable. The tag of the + conversion custom variable. It is used in the + event snippet and sent to Google Ads along with + conversion pings. For conversion uploads in + Google Ads API, the resource name of the + conversion custom variable is used. + Tag should be unique. The maximum size of tag is + 100 bytes. There should not be any extra spaces + before and after. Currently only lowercase + letters, numbers and underscores are allowed in + the tag. + status (google.ads.googleads.v12.enums.types.ConversionCustomVariableStatusEnum.ConversionCustomVariableStatus): + The status of the conversion custom variable + for conversion event accrual. + owner_customer (str): + Output only. The resource name of the + customer that owns the conversion custom + variable. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + tag = proto.Field(proto.STRING, number=4,) + status = proto.Field( + proto.ENUM, + number=5, + enum=conversion_custom_variable_status.ConversionCustomVariableStatusEnum.ConversionCustomVariableStatus, + ) + owner_customer = proto.Field(proto.STRING, number=6,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/conversion_goal_campaign_config.py b/google/ads/googleads/v12/resources/types/conversion_goal_campaign_config.py new file mode 100644 index 000000000..f7ad8fecc --- /dev/null +++ b/google/ads/googleads/v12/resources/types/conversion_goal_campaign_config.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + goal_config_level as gage_goal_config_level, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ConversionGoalCampaignConfig",}, +) + + +class ConversionGoalCampaignConfig(proto.Message): + r"""Conversion goal settings for a Campaign. + + Attributes: + resource_name (str): + Immutable. The resource name of the conversion goal campaign + config. Conversion goal campaign config resource names have + the form: + + ``customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}`` + campaign (str): + Immutable. The campaign with which this + conversion goal campaign config is associated. + goal_config_level (google.ads.googleads.v12.enums.types.GoalConfigLevelEnum.GoalConfigLevel): + The level of goal config the campaign is + using. + custom_conversion_goal (str): + The custom conversion goal the campaign is + using for optimization. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + goal_config_level = proto.Field( + proto.ENUM, + number=3, + enum=gage_goal_config_level.GoalConfigLevelEnum.GoalConfigLevel, + ) + custom_conversion_goal = proto.Field(proto.STRING, number=4,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/conversion_value_rule.py b/google/ads/googleads/v12/resources/types/conversion_value_rule.py new file mode 100644 index 000000000..ef9d05ba3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/conversion_value_rule.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import conversion_value_rule_status +from google.ads.googleads.v12.enums.types import value_rule_device_type +from google.ads.googleads.v12.enums.types import ( + value_rule_geo_location_match_type, +) +from google.ads.googleads.v12.enums.types import value_rule_operation + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRule",}, +) + + +class ConversionValueRule(proto.Message): + r"""A conversion value rule + + Attributes: + resource_name (str): + Immutable. The resource name of the conversion value rule. + Conversion value rule resource names have the form: + + ``customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}`` + id (int): + Output only. The ID of the conversion value + rule. + action (google.ads.googleads.v12.resources.types.ConversionValueRule.ValueRuleAction): + Action applied when the rule is triggered. + geo_location_condition (google.ads.googleads.v12.resources.types.ConversionValueRule.ValueRuleGeoLocationCondition): + Condition for Geo location that must be + satisfied for the value rule to apply. + device_condition (google.ads.googleads.v12.resources.types.ConversionValueRule.ValueRuleDeviceCondition): + Condition for device type that must be + satisfied for the value rule to apply. + audience_condition (google.ads.googleads.v12.resources.types.ConversionValueRule.ValueRuleAudienceCondition): + Condition for audience that must be satisfied + for the value rule to apply. + owner_customer (str): + Output only. The resource name of the conversion value + rule's owner customer. When the value rule is inherited from + a manager customer, owner_customer will be the resource name + of the manager whereas the customer in the resource_name + will be of the requesting serving customer. \*\* Read-only + \*\* + status (google.ads.googleads.v12.enums.types.ConversionValueRuleStatusEnum.ConversionValueRuleStatus): + The status of the conversion value rule. + """ + + class ValueRuleAction(proto.Message): + r"""Action applied when rule is applied. + + Attributes: + operation (google.ads.googleads.v12.enums.types.ValueRuleOperationEnum.ValueRuleOperation): + Specifies applied operation. + value (float): + Specifies applied value. + """ + + operation = proto.Field( + proto.ENUM, + number=1, + enum=value_rule_operation.ValueRuleOperationEnum.ValueRuleOperation, + ) + value = proto.Field(proto.DOUBLE, number=2,) + + class ValueRuleGeoLocationCondition(proto.Message): + r"""Condition on Geo dimension. + + Attributes: + excluded_geo_target_constants (Sequence[str]): + Geo locations that advertisers want to + exclude. + excluded_geo_match_type (google.ads.googleads.v12.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): + Excluded Geo location match type. + geo_target_constants (Sequence[str]): + Geo locations that advertisers want to + include. + geo_match_type (google.ads.googleads.v12.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): + Included Geo location match type. + """ + + excluded_geo_target_constants = proto.RepeatedField( + proto.STRING, number=1, + ) + excluded_geo_match_type = proto.Field( + proto.ENUM, + number=2, + enum=value_rule_geo_location_match_type.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType, + ) + geo_target_constants = proto.RepeatedField(proto.STRING, number=3,) + geo_match_type = proto.Field( + proto.ENUM, + number=4, + enum=value_rule_geo_location_match_type.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType, + ) + + class ValueRuleDeviceCondition(proto.Message): + r"""Condition on Device dimension. + + Attributes: + device_types (Sequence[google.ads.googleads.v12.enums.types.ValueRuleDeviceTypeEnum.ValueRuleDeviceType]): + Value for device type condition. + """ + + device_types = proto.RepeatedField( + proto.ENUM, + number=1, + enum=value_rule_device_type.ValueRuleDeviceTypeEnum.ValueRuleDeviceType, + ) + + class ValueRuleAudienceCondition(proto.Message): + r"""Condition on Audience dimension. + + Attributes: + user_lists (Sequence[str]): + User Lists. + user_interests (Sequence[str]): + User Interests. + """ + + user_lists = proto.RepeatedField(proto.STRING, number=1,) + user_interests = proto.RepeatedField(proto.STRING, number=2,) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + action = proto.Field(proto.MESSAGE, number=3, message=ValueRuleAction,) + geo_location_condition = proto.Field( + proto.MESSAGE, number=4, message=ValueRuleGeoLocationCondition, + ) + device_condition = proto.Field( + proto.MESSAGE, number=5, message=ValueRuleDeviceCondition, + ) + audience_condition = proto.Field( + proto.MESSAGE, number=6, message=ValueRuleAudienceCondition, + ) + owner_customer = proto.Field(proto.STRING, number=7,) + status = proto.Field( + proto.ENUM, + number=8, + enum=conversion_value_rule_status.ConversionValueRuleStatusEnum.ConversionValueRuleStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/conversion_value_rule_set.py b/google/ads/googleads/v12/resources/types/conversion_value_rule_set.py new file mode 100644 index 000000000..2c0b0894b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/conversion_value_rule_set.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import conversion_action_category +from google.ads.googleads.v12.enums.types import ( + conversion_value_rule_set_status, +) +from google.ads.googleads.v12.enums.types import value_rule_set_attachment_type +from google.ads.googleads.v12.enums.types import value_rule_set_dimension + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ConversionValueRuleSet",}, +) + + +class ConversionValueRuleSet(proto.Message): + r"""A conversion value rule set + + Attributes: + resource_name (str): + Immutable. The resource name of the conversion value rule + set. Conversion value rule set resource names have the form: + + ``customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}`` + id (int): + Output only. The ID of the conversion value + rule set. + conversion_value_rules (Sequence[str]): + Resource names of rules within the rule set. + dimensions (Sequence[google.ads.googleads.v12.enums.types.ValueRuleSetDimensionEnum.ValueRuleSetDimension]): + Defines dimensions for Value Rule conditions. + The condition types of value rules within this + value rule set must be of these dimensions. The + first entry in this list is the primary + dimension of the included value rules. When + using value rule primary dimension segmentation, + conversion values will be segmented into the + values adjusted by value rules and the original + values, if some value rules apply. + owner_customer (str): + Output only. The resource name of the conversion value rule + set's owner customer. When the value rule set is inherited + from a manager customer, owner_customer will be the resource + name of the manager whereas the customer in the + resource_name will be of the requesting serving customer. + \*\* Read-only \*\* + attachment_type (google.ads.googleads.v12.enums.types.ValueRuleSetAttachmentTypeEnum.ValueRuleSetAttachmentType): + Immutable. Defines the scope where the + conversion value rule set is attached. + campaign (str): + The resource name of the campaign when the + conversion value rule set is attached to a + campaign. + status (google.ads.googleads.v12.enums.types.ConversionValueRuleSetStatusEnum.ConversionValueRuleSetStatus): + Output only. The status of the conversion value rule set. + \*\* Read-only \*\* + conversion_action_categories (Sequence[google.ads.googleads.v12.enums.types.ConversionActionCategoryEnum.ConversionActionCategory]): + Immutable. The conversion action categories + of the conversion value rule set. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + conversion_value_rules = proto.RepeatedField(proto.STRING, number=3,) + dimensions = proto.RepeatedField( + proto.ENUM, + number=4, + enum=value_rule_set_dimension.ValueRuleSetDimensionEnum.ValueRuleSetDimension, + ) + owner_customer = proto.Field(proto.STRING, number=5,) + attachment_type = proto.Field( + proto.ENUM, + number=6, + enum=value_rule_set_attachment_type.ValueRuleSetAttachmentTypeEnum.ValueRuleSetAttachmentType, + ) + campaign = proto.Field(proto.STRING, number=7,) + status = proto.Field( + proto.ENUM, + number=8, + enum=conversion_value_rule_set_status.ConversionValueRuleSetStatusEnum.ConversionValueRuleSetStatus, + ) + conversion_action_categories = proto.RepeatedField( + proto.ENUM, + number=9, + enum=conversion_action_category.ConversionActionCategoryEnum.ConversionActionCategory, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/currency_constant.py b/google/ads/googleads/v12/resources/types/currency_constant.py new file mode 100644 index 000000000..f894ef29e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/currency_constant.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CurrencyConstant",}, +) + + +class CurrencyConstant(proto.Message): + r"""A currency constant. + + Attributes: + resource_name (str): + Output only. The resource name of the currency constant. + Currency constant resource names have the form: + + ``currencyConstants/{code}`` + code (str): + Output only. ISO 4217 three-letter currency + code, for example, "USD". + + This field is a member of `oneof`_ ``_code``. + name (str): + Output only. Full English name of the + currency. + + This field is a member of `oneof`_ ``_name``. + symbol (str): + Output only. Standard symbol for describing + this currency, for example, '$' for US Dollars. + + This field is a member of `oneof`_ ``_symbol``. + billable_unit_micros (int): + Output only. The billable unit for this + currency. Billed amounts should be multiples of + this value. + + This field is a member of `oneof`_ ``_billable_unit_micros``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + code = proto.Field(proto.STRING, number=6, optional=True,) + name = proto.Field(proto.STRING, number=7, optional=True,) + symbol = proto.Field(proto.STRING, number=8, optional=True,) + billable_unit_micros = proto.Field(proto.INT64, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/custom_audience.py b/google/ads/googleads/v12/resources/types/custom_audience.py new file mode 100644 index 000000000..ef5d55355 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/custom_audience.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import custom_audience_member_type +from google.ads.googleads.v12.enums.types import custom_audience_status +from google.ads.googleads.v12.enums.types import custom_audience_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomAudience", "CustomAudienceMember",}, +) + + +class CustomAudience(proto.Message): + r"""A custom audience. This is a list of users by interest. + + Attributes: + resource_name (str): + Immutable. The resource name of the custom audience. Custom + audience resource names have the form: + + ``customers/{customer_id}/customAudiences/{custom_audience_id}`` + id (int): + Output only. ID of the custom audience. + status (google.ads.googleads.v12.enums.types.CustomAudienceStatusEnum.CustomAudienceStatus): + Output only. Status of this custom audience. + Indicates whether the custom audience is enabled + or removed. + name (str): + Name of the custom audience. It should be + unique for all custom audiences created by a + customer. This field is required for creating + operations. + type_ (google.ads.googleads.v12.enums.types.CustomAudienceTypeEnum.CustomAudienceType): + Type of the custom audience. ("INTEREST" OR + "PURCHASE_INTENT" is not allowed for newly created custom + audience but kept for existing audiences) + description (str): + Description of this custom audience. + members (Sequence[google.ads.googleads.v12.resources.types.CustomAudienceMember]): + List of custom audience members that this + custom audience is composed of. Members can be + added during CustomAudience creation. If members + are presented in UPDATE operation, existing + members will be overridden. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + status = proto.Field( + proto.ENUM, + number=3, + enum=custom_audience_status.CustomAudienceStatusEnum.CustomAudienceStatus, + ) + name = proto.Field(proto.STRING, number=4,) + type_ = proto.Field( + proto.ENUM, + number=5, + enum=custom_audience_type.CustomAudienceTypeEnum.CustomAudienceType, + ) + description = proto.Field(proto.STRING, number=6,) + members = proto.RepeatedField( + proto.MESSAGE, number=7, message="CustomAudienceMember", + ) + + +class CustomAudienceMember(proto.Message): + r"""A member of custom audience. A member can be a KEYWORD, URL, + PLACE_CATEGORY or APP. It can only be created or removed but not + changed. + + 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: + member_type (google.ads.googleads.v12.enums.types.CustomAudienceMemberTypeEnum.CustomAudienceMemberType): + The type of custom audience member, KEYWORD, URL, + PLACE_CATEGORY or APP. + keyword (str): + A keyword or keyword phrase — at most 10 + words and 80 characters. Languages with + double-width characters such as Chinese, + Japanese, or Korean, are allowed 40 characters, + which describes the user's interests or actions. + + This field is a member of `oneof`_ ``value``. + url (str): + An HTTP URL, protocol-included — at most 2048 + characters, which includes contents users have + interests in. + + This field is a member of `oneof`_ ``value``. + place_category (int): + A place type described by a place category + users visit. + + This field is a member of `oneof`_ ``value``. + app (str): + A package name of Android apps which users + installed such as com.google.example. + + This field is a member of `oneof`_ ``value``. + """ + + member_type = proto.Field( + proto.ENUM, + number=1, + enum=custom_audience_member_type.CustomAudienceMemberTypeEnum.CustomAudienceMemberType, + ) + keyword = proto.Field(proto.STRING, number=2, oneof="value",) + url = proto.Field(proto.STRING, number=3, oneof="value",) + place_category = proto.Field(proto.INT64, number=4, oneof="value",) + app = proto.Field(proto.STRING, number=5, oneof="value",) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/custom_conversion_goal.py b/google/ads/googleads/v12/resources/types/custom_conversion_goal.py new file mode 100644 index 000000000..7421d4619 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/custom_conversion_goal.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import custom_conversion_goal_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomConversionGoal",}, +) + + +class CustomConversionGoal(proto.Message): + r"""Custom conversion goal that can make arbitrary conversion + actions biddable. + + Attributes: + resource_name (str): + Immutable. The resource name of the custom conversion goal. + Custom conversion goal resource names have the form: + + ``customers/{customer_id}/customConversionGoals/{goal_id}`` + id (int): + Immutable. The ID for this custom conversion + goal. + name (str): + The name for this custom conversion goal. + conversion_actions (Sequence[str]): + Conversion actions that the custom conversion + goal makes biddable. + status (google.ads.googleads.v12.enums.types.CustomConversionGoalStatusEnum.CustomConversionGoalStatus): + The status of the custom conversion goal. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + conversion_actions = proto.RepeatedField(proto.STRING, number=4,) + status = proto.Field( + proto.ENUM, + number=5, + enum=custom_conversion_goal_status.CustomConversionGoalStatusEnum.CustomConversionGoalStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/custom_interest.py b/google/ads/googleads/v12/resources/types/custom_interest.py new file mode 100644 index 000000000..89318c20c --- /dev/null +++ b/google/ads/googleads/v12/resources/types/custom_interest.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import custom_interest_member_type +from google.ads.googleads.v12.enums.types import custom_interest_status +from google.ads.googleads.v12.enums.types import custom_interest_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomInterest", "CustomInterestMember",}, +) + + +class CustomInterest(proto.Message): + r"""A custom interest. This is a list of users by interest. + + Attributes: + resource_name (str): + Immutable. The resource name of the custom interest. Custom + interest resource names have the form: + + ``customers/{customer_id}/customInterests/{custom_interest_id}`` + id (int): + Output only. Id of the custom interest. + + This field is a member of `oneof`_ ``_id``. + status (google.ads.googleads.v12.enums.types.CustomInterestStatusEnum.CustomInterestStatus): + Status of this custom interest. Indicates + whether the custom interest is enabled or + removed. + name (str): + Name of the custom interest. It should be + unique across the same custom affinity audience. + This field is required for create operations. + + This field is a member of `oneof`_ ``_name``. + type_ (google.ads.googleads.v12.enums.types.CustomInterestTypeEnum.CustomInterestType): + Type of the custom interest, CUSTOM_AFFINITY or + CUSTOM_INTENT. By default the type is set to + CUSTOM_AFFINITY. + description (str): + Description of this custom interest audience. + + This field is a member of `oneof`_ ``_description``. + members (Sequence[google.ads.googleads.v12.resources.types.CustomInterestMember]): + List of custom interest members that this + custom interest is composed of. Members can be + added during CustomInterest creation. If members + are presented in UPDATE operation, existing + members will be overridden. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=8, optional=True,) + status = proto.Field( + proto.ENUM, + number=3, + enum=custom_interest_status.CustomInterestStatusEnum.CustomInterestStatus, + ) + name = proto.Field(proto.STRING, number=9, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=5, + enum=custom_interest_type.CustomInterestTypeEnum.CustomInterestType, + ) + description = proto.Field(proto.STRING, number=10, optional=True,) + members = proto.RepeatedField( + proto.MESSAGE, number=7, message="CustomInterestMember", + ) + + +class CustomInterestMember(proto.Message): + r"""A member of custom interest audience. A member can be a + keyword or url. It is immutable, that is, it can only be created + or removed but not changed. + + Attributes: + member_type (google.ads.googleads.v12.enums.types.CustomInterestMemberTypeEnum.CustomInterestMemberType): + The type of custom interest member, KEYWORD + or URL. + parameter (str): + Keyword text when member_type is KEYWORD or URL string when + member_type is URL. + + This field is a member of `oneof`_ ``_parameter``. + """ + + member_type = proto.Field( + proto.ENUM, + number=1, + enum=custom_interest_member_type.CustomInterestMemberTypeEnum.CustomInterestMemberType, + ) + parameter = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer.py b/google/ads/googleads/v12/resources/types/customer.py new file mode 100644 index 000000000..95ebda6ce --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import conversion_tracking_status_enum +from google.ads.googleads.v12.enums.types import ( + customer_pay_per_conversion_eligibility_failure_reason, +) +from google.ads.googleads.v12.enums.types import customer_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={ + "Customer", + "CallReportingSetting", + "ConversionTrackingSetting", + "RemarketingSetting", + }, +) + + +class Customer(proto.Message): + r"""A customer. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer. Customer + resource names have the form: + + ``customers/{customer_id}`` + id (int): + Output only. The ID of the customer. + + This field is a member of `oneof`_ ``_id``. + descriptive_name (str): + Optional, non-unique descriptive name of the + customer. + + This field is a member of `oneof`_ ``_descriptive_name``. + currency_code (str): + Immutable. The currency in which the account + operates. A subset of the currency codes from + the ISO 4217 standard is supported. + + This field is a member of `oneof`_ ``_currency_code``. + time_zone (str): + Immutable. The local timezone ID of the + customer. + + This field is a member of `oneof`_ ``_time_zone``. + tracking_url_template (str): + The URL template for constructing a tracking + URL out of parameters. + + This field is a member of `oneof`_ ``_tracking_url_template``. + final_url_suffix (str): + The URL template for appending params to the + final URL + + This field is a member of `oneof`_ ``_final_url_suffix``. + auto_tagging_enabled (bool): + Whether auto-tagging is enabled for the + customer. + + This field is a member of `oneof`_ ``_auto_tagging_enabled``. + has_partners_badge (bool): + Output only. Whether the Customer has a + Partners program badge. If the Customer is not + associated with the Partners program, this will + be false. For more information, see + https://support.google.com/partners/answer/3125774. + + This field is a member of `oneof`_ ``_has_partners_badge``. + manager (bool): + Output only. Whether the customer is a + manager. + + This field is a member of `oneof`_ ``_manager``. + test_account (bool): + Output only. Whether the customer is a test + account. + + This field is a member of `oneof`_ ``_test_account``. + call_reporting_setting (google.ads.googleads.v12.resources.types.CallReportingSetting): + Call reporting setting for a customer. Only mutable in an + ``update`` operation. + conversion_tracking_setting (google.ads.googleads.v12.resources.types.ConversionTrackingSetting): + Output only. Conversion tracking setting for + a customer. + remarketing_setting (google.ads.googleads.v12.resources.types.RemarketingSetting): + Output only. Remarketing setting for a + customer. + pay_per_conversion_eligibility_failure_reasons (Sequence[google.ads.googleads.v12.enums.types.CustomerPayPerConversionEligibilityFailureReasonEnum.CustomerPayPerConversionEligibilityFailureReason]): + Output only. Reasons why the customer is not + eligible to use PaymentMode.CONVERSIONS. If the + list is empty, the customer is eligible. This + field is read-only. + optimization_score (float): + Output only. Optimization score of the + customer. + Optimization score is an estimate of how well a + customer's campaigns are set to perform. It + ranges from 0% (0.0) to 100% (1.0). This field + is null for all manager customers, and for + unscored non-manager customers. + See "About optimization score" at + https://support.google.com/google-ads/answer/9061546. + This field is read-only. + + This field is a member of `oneof`_ ``_optimization_score``. + optimization_score_weight (float): + Output only. Optimization score weight of the customer. + + Optimization score weight can be used to compare/aggregate + optimization scores across multiple non-manager customers. + The aggregate optimization score of a manager is computed as + the sum over all of their customers of + ``Customer.optimization_score * Customer.optimization_score_weight``. + This field is 0 for all manager customers, and for unscored + non-manager customers. + + This field is read-only. + status (google.ads.googleads.v12.enums.types.CustomerStatusEnum.CustomerStatus): + Output only. The status of the customer. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=19, optional=True,) + descriptive_name = proto.Field(proto.STRING, number=20, optional=True,) + currency_code = proto.Field(proto.STRING, number=21, optional=True,) + time_zone = proto.Field(proto.STRING, number=22, optional=True,) + tracking_url_template = proto.Field(proto.STRING, number=23, optional=True,) + final_url_suffix = proto.Field(proto.STRING, number=24, optional=True,) + auto_tagging_enabled = proto.Field(proto.BOOL, number=25, optional=True,) + has_partners_badge = proto.Field(proto.BOOL, number=26, optional=True,) + manager = proto.Field(proto.BOOL, number=27, optional=True,) + test_account = proto.Field(proto.BOOL, number=28, optional=True,) + call_reporting_setting = proto.Field( + proto.MESSAGE, number=10, message="CallReportingSetting", + ) + conversion_tracking_setting = proto.Field( + proto.MESSAGE, number=14, message="ConversionTrackingSetting", + ) + remarketing_setting = proto.Field( + proto.MESSAGE, number=15, message="RemarketingSetting", + ) + pay_per_conversion_eligibility_failure_reasons = proto.RepeatedField( + proto.ENUM, + number=16, + enum=customer_pay_per_conversion_eligibility_failure_reason.CustomerPayPerConversionEligibilityFailureReasonEnum.CustomerPayPerConversionEligibilityFailureReason, + ) + optimization_score = proto.Field(proto.DOUBLE, number=29, optional=True,) + optimization_score_weight = proto.Field(proto.DOUBLE, number=30,) + status = proto.Field( + proto.ENUM, + number=36, + enum=customer_status.CustomerStatusEnum.CustomerStatus, + ) + + +class CallReportingSetting(proto.Message): + r"""Call reporting setting for a customer. Only mutable in an ``update`` + operation. + + Attributes: + call_reporting_enabled (bool): + Enable reporting of phone call events by + redirecting them through Google System. + + This field is a member of `oneof`_ ``_call_reporting_enabled``. + call_conversion_reporting_enabled (bool): + Whether to enable call conversion reporting. + + This field is a member of `oneof`_ ``_call_conversion_reporting_enabled``. + call_conversion_action (str): + Customer-level call conversion action to attribute a call + conversion to. If not set a default conversion action is + used. Only in effect when call_conversion_reporting_enabled + is set to true. + + This field is a member of `oneof`_ ``_call_conversion_action``. + """ + + call_reporting_enabled = proto.Field(proto.BOOL, number=10, optional=True,) + call_conversion_reporting_enabled = proto.Field( + proto.BOOL, number=11, optional=True, + ) + call_conversion_action = proto.Field( + proto.STRING, number=12, optional=True, + ) + + +class ConversionTrackingSetting(proto.Message): + r"""A collection of customer-wide settings related to Google Ads + Conversion Tracking. + + Attributes: + conversion_tracking_id (int): + Output only. The conversion tracking id used for this + account. This id doesn't indicate whether the customer uses + conversion tracking (conversion_tracking_status does). This + field is read-only. + + This field is a member of `oneof`_ ``_conversion_tracking_id``. + cross_account_conversion_tracking_id (int): + Output only. The conversion tracking id of the customer's + manager. This is set when the customer is opted into cross + account conversion tracking, and it overrides + conversion_tracking_id. This field can only be managed + through the Google Ads UI. This field is read-only. + + This field is a member of `oneof`_ ``_cross_account_conversion_tracking_id``. + accepted_customer_data_terms (bool): + Output only. Whether the customer has + accepted customer data terms. If using + cross-account conversion tracking, this value is + inherited from the manager. This field is + read-only. For more + information, see + https://support.google.com/adspolicy/answer/7475709. + conversion_tracking_status (google.ads.googleads.v12.enums.types.ConversionTrackingStatusEnum.ConversionTrackingStatus): + Output only. Conversion tracking status. It indicates + whether the customer is using conversion tracking, and who + is the conversion tracking owner of this customer. If this + customer is using cross-account conversion tracking, the + value returned will differ based on the + ``login-customer-id`` of the request. + enhanced_conversions_for_leads_enabled (bool): + Output only. Whether the customer is opted-in + for enhanced conversions for leads. If using + cross-account conversion tracking, this value is + inherited from the manager. This field is + read-only. + google_ads_conversion_customer (str): + Output only. The resource name of the + customer where conversions are created and + managed. This field is read-only. + """ + + conversion_tracking_id = proto.Field(proto.INT64, number=3, optional=True,) + cross_account_conversion_tracking_id = proto.Field( + proto.INT64, number=4, optional=True, + ) + accepted_customer_data_terms = proto.Field(proto.BOOL, number=5,) + conversion_tracking_status = proto.Field( + proto.ENUM, + number=6, + enum=conversion_tracking_status_enum.ConversionTrackingStatusEnum.ConversionTrackingStatus, + ) + enhanced_conversions_for_leads_enabled = proto.Field(proto.BOOL, number=7,) + google_ads_conversion_customer = proto.Field(proto.STRING, number=8,) + + +class RemarketingSetting(proto.Message): + r"""Remarketing setting for a customer. + + Attributes: + google_global_site_tag (str): + Output only. The Google tag. + + This field is a member of `oneof`_ ``_google_global_site_tag``. + """ + + google_global_site_tag = proto.Field(proto.STRING, number=2, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_asset.py b/google/ads/googleads/v12/resources/types/customer_asset.py new file mode 100644 index 000000000..73d4061ae --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_asset.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_field_type +from google.ads.googleads.v12.enums.types import asset_link_status +from google.ads.googleads.v12.enums.types import asset_source + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerAsset",}, +) + + +class CustomerAsset(proto.Message): + r"""A link between a customer and an asset. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer asset. + CustomerAsset resource names have the form: + + ``customers/{customer_id}/customerAssets/{asset_id}~{field_type}`` + asset (str): + Required. Immutable. The asset which is + linked to the customer. + field_type (google.ads.googleads.v12.enums.types.AssetFieldTypeEnum.AssetFieldType): + Required. Immutable. Role that the asset + takes for the customer link. + source (google.ads.googleads.v12.enums.types.AssetSourceEnum.AssetSource): + Output only. Source of the customer asset + link. + status (google.ads.googleads.v12.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + Status of the customer asset. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset = proto.Field(proto.STRING, number=2,) + field_type = proto.Field( + proto.ENUM, + number=3, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + source = proto.Field( + proto.ENUM, number=5, enum=asset_source.AssetSourceEnum.AssetSource, + ) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_link_status.AssetLinkStatusEnum.AssetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_asset_set.py b/google/ads/googleads/v12/resources/types/customer_asset_set.py new file mode 100644 index 000000000..0316c5789 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_asset_set.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import asset_set_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerAssetSet",}, +) + + +class CustomerAssetSet(proto.Message): + r"""CustomerAssetSet is the linkage between a customer and an + asset set. Adding a CustomerAssetSet links an asset set with a + customer. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer asset set. + Asset set asset resource names have the form: + + ``customers/{customer_id}/customerAssetSets/{asset_set_id}`` + asset_set (str): + Immutable. The asset set which is linked to + the customer. + customer (str): + Immutable. The customer to which this asset + set is linked. + status (google.ads.googleads.v12.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + Output only. The status of the customer asset + set asset. Read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_set = proto.Field(proto.STRING, number=2,) + customer = proto.Field(proto.STRING, number=3,) + status = proto.Field( + proto.ENUM, + number=4, + enum=asset_set_link_status.AssetSetLinkStatusEnum.AssetSetLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_client.py b/google/ads/googleads/v12/resources/types/customer_client.py new file mode 100644 index 000000000..369e2279a --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_client.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import customer_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerClient",}, +) + + +class CustomerClient(proto.Message): + r"""A link between the given customer and a client customer. + CustomerClients only exist for manager customers. All direct and + indirect client customers are included, as well as the manager + itself. + + Attributes: + resource_name (str): + Output only. The resource name of the customer client. + CustomerClient resource names have the form: + ``customers/{customer_id}/customerClients/{client_customer_id}`` + client_customer (str): + Output only. The resource name of the + client-customer which is linked to the given + customer. Read only. + + This field is a member of `oneof`_ ``_client_customer``. + hidden (bool): + Output only. Specifies whether this is a `hidden + account `__. + Read only. + + This field is a member of `oneof`_ ``_hidden``. + level (int): + Output only. Distance between given customer + and client. For self link, the level value will + be 0. Read only. + + This field is a member of `oneof`_ ``_level``. + time_zone (str): + Output only. Common Locale Data Repository (CLDR) string + representation of the time zone of the client, for example, + America/Los_Angeles. Read only. + + This field is a member of `oneof`_ ``_time_zone``. + test_account (bool): + Output only. Identifies if the client is a + test account. Read only. + + This field is a member of `oneof`_ ``_test_account``. + manager (bool): + Output only. Identifies if the client is a + manager. Read only. + + This field is a member of `oneof`_ ``_manager``. + descriptive_name (str): + Output only. Descriptive name for the client. + Read only. + + This field is a member of `oneof`_ ``_descriptive_name``. + currency_code (str): + Output only. Currency code (for example, + 'USD', 'EUR') for the client. Read only. + + This field is a member of `oneof`_ ``_currency_code``. + id (int): + Output only. The ID of the client customer. + Read only. + + This field is a member of `oneof`_ ``_id``. + applied_labels (Sequence[str]): + Output only. The resource names of the labels owned by the + requesting customer that are applied to the client customer. + Label resource names have the form: + + ``customers/{customer_id}/labels/{label_id}`` + status (google.ads.googleads.v12.enums.types.CustomerStatusEnum.CustomerStatus): + Output only. The status of the client + customer. Read only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + client_customer = proto.Field(proto.STRING, number=12, optional=True,) + hidden = proto.Field(proto.BOOL, number=13, optional=True,) + level = proto.Field(proto.INT64, number=14, optional=True,) + time_zone = proto.Field(proto.STRING, number=15, optional=True,) + test_account = proto.Field(proto.BOOL, number=16, optional=True,) + manager = proto.Field(proto.BOOL, number=17, optional=True,) + descriptive_name = proto.Field(proto.STRING, number=18, optional=True,) + currency_code = proto.Field(proto.STRING, number=19, optional=True,) + id = proto.Field(proto.INT64, number=20, optional=True,) + applied_labels = proto.RepeatedField(proto.STRING, number=21,) + status = proto.Field( + proto.ENUM, + number=22, + enum=customer_status.CustomerStatusEnum.CustomerStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_client_link.py b/google/ads/googleads/v12/resources/types/customer_client_link.py new file mode 100644 index 000000000..1baa4feb8 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_client_link.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import manager_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerClientLink",}, +) + + +class CustomerClientLink(proto.Message): + r"""Represents customer client link relationship. + + Attributes: + resource_name (str): + Immutable. Name of the resource. CustomerClientLink resource + names have the form: + ``customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}`` + client_customer (str): + Immutable. The client customer linked to this + customer. + + This field is a member of `oneof`_ ``_client_customer``. + manager_link_id (int): + Output only. This is uniquely identifies a + customer client link. Read only. + + This field is a member of `oneof`_ ``_manager_link_id``. + status (google.ads.googleads.v12.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): + This is the status of the link between client + and manager. + hidden (bool): + The visibility of the link. Users can choose + whether or not to see hidden links in the Google + Ads UI. Default value is false + + This field is a member of `oneof`_ ``_hidden``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + client_customer = proto.Field(proto.STRING, number=7, optional=True,) + manager_link_id = proto.Field(proto.INT64, number=8, optional=True,) + status = proto.Field( + proto.ENUM, + number=5, + enum=manager_link_status.ManagerLinkStatusEnum.ManagerLinkStatus, + ) + hidden = proto.Field(proto.BOOL, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_conversion_goal.py b/google/ads/googleads/v12/resources/types/customer_conversion_goal.py new file mode 100644 index 000000000..631220c6e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_conversion_goal.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import conversion_action_category +from google.ads.googleads.v12.enums.types import conversion_origin + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerConversionGoal",}, +) + + +class CustomerConversionGoal(proto.Message): + r"""Biddability control for conversion actions with a matching + category and origin. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer conversion + goal. Customer conversion goal resource names have the form: + + ``customers/{customer_id}/customerConversionGoals/{category}~{origin}`` + category (google.ads.googleads.v12.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + The conversion category of this customer + conversion goal. Only conversion actions that + have this category will be included in this + goal. + origin (google.ads.googleads.v12.enums.types.ConversionOriginEnum.ConversionOrigin): + The conversion origin of this customer + conversion goal. Only conversion actions that + have this conversion origin will be included in + this goal. + biddable (bool): + The biddability of the customer conversion + goal. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + category = proto.Field( + proto.ENUM, + number=2, + enum=conversion_action_category.ConversionActionCategoryEnum.ConversionActionCategory, + ) + origin = proto.Field( + proto.ENUM, + number=3, + enum=conversion_origin.ConversionOriginEnum.ConversionOrigin, + ) + biddable = proto.Field(proto.BOOL, number=4,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_customizer.py b/google/ads/googleads/v12/resources/types/customer_customizer.py new file mode 100644 index 000000000..d31a0c7e2 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_customizer.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import customizer_value +from google.ads.googleads.v12.enums.types import customizer_value_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerCustomizer",}, +) + + +class CustomerCustomizer(proto.Message): + r"""A customizer value for the associated CustomizerAttribute at + the Customer level. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer customizer. + Customer customizer resource names have the form: + + ``customers/{customer_id}/customerCustomizers/{customizer_attribute_id}`` + customizer_attribute (str): + Required. Immutable. The customizer attribute + which is linked to the customer. + status (google.ads.googleads.v12.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + Output only. The status of the customer + customizer attribute. + value (google.ads.googleads.v12.common.types.CustomizerValue): + Required. The value to associate with the + customizer attribute at this level. The value + must be of the type specified for the + CustomizerAttribute. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customizer_attribute = proto.Field(proto.STRING, number=2,) + status = proto.Field( + proto.ENUM, + number=3, + enum=customizer_value_status.CustomizerValueStatusEnum.CustomizerValueStatus, + ) + value = proto.Field( + proto.MESSAGE, number=4, message=customizer_value.CustomizerValue, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_extension_setting.py b/google/ads/googleads/v12/resources/types/customer_extension_setting.py new file mode 100644 index 000000000..c0ea02a97 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_extension_setting.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import extension_setting_device +from google.ads.googleads.v12.enums.types import ( + extension_type as gage_extension_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerExtensionSetting",}, +) + + +class CustomerExtensionSetting(proto.Message): + r"""A customer extension setting. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer extension + setting. CustomerExtensionSetting resource names have the + form: + + ``customers/{customer_id}/customerExtensionSettings/{extension_type}`` + extension_type (google.ads.googleads.v12.enums.types.ExtensionTypeEnum.ExtensionType): + Immutable. The extension type of the customer + extension setting. + extension_feed_items (Sequence[str]): + The resource names of the extension feed items to serve + under the customer. ExtensionFeedItem resource names have + the form: + + ``customers/{customer_id}/extensionFeedItems/{feed_item_id}`` + device (google.ads.googleads.v12.enums.types.ExtensionSettingDeviceEnum.ExtensionSettingDevice): + The device for which the extensions will + serve. Optional. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + extension_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_extension_type.ExtensionTypeEnum.ExtensionType, + ) + extension_feed_items = proto.RepeatedField(proto.STRING, number=5,) + device = proto.Field( + proto.ENUM, + number=4, + enum=extension_setting_device.ExtensionSettingDeviceEnum.ExtensionSettingDevice, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_feed.py b/google/ads/googleads/v12/resources/types/customer_feed.py new file mode 100644 index 000000000..ecf9b72ab --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_feed.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + matching_function as gagc_matching_function, +) +from google.ads.googleads.v12.enums.types import feed_link_status +from google.ads.googleads.v12.enums.types import placeholder_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerFeed",}, +) + + +class CustomerFeed(proto.Message): + r"""A customer feed. + + Attributes: + resource_name (str): + Immutable. The resource name of the customer feed. Customer + feed resource names have the form: + + ``customers/{customer_id}/customerFeeds/{feed_id}`` + feed (str): + Immutable. The feed being linked to the + customer. + + This field is a member of `oneof`_ ``_feed``. + placeholder_types (Sequence[google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType]): + Indicates which placeholder types the feed + may populate under the connected customer. + Required. + matching_function (google.ads.googleads.v12.common.types.MatchingFunction): + Matching function associated with the + CustomerFeed. The matching function is used to + filter the set of feed items selected. Required. + status (google.ads.googleads.v12.enums.types.FeedLinkStatusEnum.FeedLinkStatus): + Output only. Status of the customer feed. + This field is read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=6, optional=True,) + placeholder_types = proto.RepeatedField( + proto.ENUM, + number=3, + enum=placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + matching_function = proto.Field( + proto.MESSAGE, + number=4, + message=gagc_matching_function.MatchingFunction, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=feed_link_status.FeedLinkStatusEnum.FeedLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_label.py b/google/ads/googleads/v12/resources/types/customer_label.py new file mode 100644 index 000000000..61654fd1c --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_label.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerLabel",}, +) + + +class CustomerLabel(proto.Message): + r"""Represents a relationship between a customer and a label. + This customer may not have access to all the labels attached to + it. Additional CustomerLabels may be returned by increasing + permissions with login-customer-id. + + Attributes: + resource_name (str): + Immutable. Name of the resource. Customer label resource + names have the form: + ``customers/{customer_id}/customerLabels/{label_id}`` + customer (str): + Output only. The resource name of the + customer to which the label is attached. Read + only. + + This field is a member of `oneof`_ ``_customer``. + label (str): + Output only. The resource name of the label + assigned to the customer. + Note: the Customer ID portion of the label + resource name is not validated when creating a + new CustomerLabel. + + This field is a member of `oneof`_ ``_label``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer = proto.Field(proto.STRING, number=4, optional=True,) + label = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_manager_link.py b/google/ads/googleads/v12/resources/types/customer_manager_link.py new file mode 100644 index 000000000..b8ae3e753 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_manager_link.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import manager_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerManagerLink",}, +) + + +class CustomerManagerLink(proto.Message): + r"""Represents customer-manager link relationship. + + Attributes: + resource_name (str): + Immutable. Name of the resource. CustomerManagerLink + resource names have the form: + ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` + manager_customer (str): + Output only. The manager customer linked to + the customer. + + This field is a member of `oneof`_ ``_manager_customer``. + manager_link_id (int): + Output only. ID of the customer-manager link. + This field is read only. + + This field is a member of `oneof`_ ``_manager_link_id``. + status (google.ads.googleads.v12.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): + Status of the link between the customer and + the manager. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + manager_customer = proto.Field(proto.STRING, number=6, optional=True,) + manager_link_id = proto.Field(proto.INT64, number=7, optional=True,) + status = proto.Field( + proto.ENUM, + number=5, + enum=manager_link_status.ManagerLinkStatusEnum.ManagerLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_negative_criterion.py b/google/ads/googleads/v12/resources/types/customer_negative_criterion.py new file mode 100644 index 000000000..593857094 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_negative_criterion.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import criterion_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerNegativeCriterion",}, +) + + +class CustomerNegativeCriterion(proto.Message): + r"""A negative criterion for exclusions at the customer level. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the customer negative + criterion. Customer negative criterion resource names have + the form: + + ``customers/{customer_id}/customerNegativeCriteria/{criterion_id}`` + id (int): + Output only. The ID of the criterion. + + This field is a member of `oneof`_ ``_id``. + type_ (google.ads.googleads.v12.enums.types.CriterionTypeEnum.CriterionType): + Output only. The type of the criterion. + content_label (google.ads.googleads.v12.common.types.ContentLabelInfo): + Immutable. ContentLabel. + + This field is a member of `oneof`_ ``criterion``. + mobile_application (google.ads.googleads.v12.common.types.MobileApplicationInfo): + Immutable. MobileApplication. + + This field is a member of `oneof`_ ``criterion``. + mobile_app_category (google.ads.googleads.v12.common.types.MobileAppCategoryInfo): + Immutable. MobileAppCategory. + + This field is a member of `oneof`_ ``criterion``. + placement (google.ads.googleads.v12.common.types.PlacementInfo): + Immutable. Placement. + + This field is a member of `oneof`_ ``criterion``. + youtube_video (google.ads.googleads.v12.common.types.YouTubeVideoInfo): + Immutable. YouTube Video. + + This field is a member of `oneof`_ ``criterion``. + youtube_channel (google.ads.googleads.v12.common.types.YouTubeChannelInfo): + Immutable. YouTube Channel. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=10, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=criterion_type.CriterionTypeEnum.CriterionType, + ) + content_label = proto.Field( + proto.MESSAGE, + number=4, + oneof="criterion", + message=criteria.ContentLabelInfo, + ) + mobile_application = proto.Field( + proto.MESSAGE, + number=5, + oneof="criterion", + message=criteria.MobileApplicationInfo, + ) + mobile_app_category = proto.Field( + proto.MESSAGE, + number=6, + oneof="criterion", + message=criteria.MobileAppCategoryInfo, + ) + placement = proto.Field( + proto.MESSAGE, + number=7, + oneof="criterion", + message=criteria.PlacementInfo, + ) + youtube_video = proto.Field( + proto.MESSAGE, + number=8, + oneof="criterion", + message=criteria.YouTubeVideoInfo, + ) + youtube_channel = proto.Field( + proto.MESSAGE, + number=9, + oneof="criterion", + message=criteria.YouTubeChannelInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_user_access.py b/google/ads/googleads/v12/resources/types/customer_user_access.py new file mode 100644 index 000000000..84f2a2f76 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_user_access.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import access_role as gage_access_role + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerUserAccess",}, +) + + +class CustomerUserAccess(proto.Message): + r"""Represents the permission of a single user onto a single + customer. + + Attributes: + resource_name (str): + Immutable. Name of the resource. Resource names have the + form: + ``customers/{customer_id}/customerUserAccesses/{user_id}`` + user_id (int): + Output only. User id of the user with the + customer access. Read only field + email_address (str): + Output only. Email address of the user. + Read only field + + This field is a member of `oneof`_ ``_email_address``. + access_role (google.ads.googleads.v12.enums.types.AccessRoleEnum.AccessRole): + Access role of the user. + access_creation_date_time (str): + Output only. The customer user access + creation time. Read only field + The format is "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_access_creation_date_time``. + inviter_user_email_address (str): + Output only. The email address of the inviter + user. Read only field + + This field is a member of `oneof`_ ``_inviter_user_email_address``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + user_id = proto.Field(proto.INT64, number=2,) + email_address = proto.Field(proto.STRING, number=3, optional=True,) + access_role = proto.Field( + proto.ENUM, number=4, enum=gage_access_role.AccessRoleEnum.AccessRole, + ) + access_creation_date_time = proto.Field( + proto.STRING, number=6, optional=True, + ) + inviter_user_email_address = proto.Field( + proto.STRING, number=7, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customer_user_access_invitation.py b/google/ads/googleads/v12/resources/types/customer_user_access_invitation.py new file mode 100644 index 000000000..b1afbf1f1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customer_user_access_invitation.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import access_invitation_status +from google.ads.googleads.v12.enums.types import access_role as gage_access_role + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomerUserAccessInvitation",}, +) + + +class CustomerUserAccessInvitation(proto.Message): + r"""Represent an invitation to a new user on this customer + account. + + Attributes: + resource_name (str): + Immutable. Name of the resource. Resource names have the + form: + ``customers/{customer_id}/customerUserAccessInvitations/{invitation_id}`` + invitation_id (int): + Output only. The ID of the invitation. + This field is read-only. + access_role (google.ads.googleads.v12.enums.types.AccessRoleEnum.AccessRole): + Immutable. Access role of the user. + email_address (str): + Immutable. Email address the invitation was + sent to. This can differ from the email address + of the account that accepts the invite. + creation_date_time (str): + Output only. Time invitation was created. + This field is read-only. + The format is "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + invitation_status (google.ads.googleads.v12.enums.types.AccessInvitationStatusEnum.AccessInvitationStatus): + Output only. Invitation status of the user. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + invitation_id = proto.Field(proto.INT64, number=2,) + access_role = proto.Field( + proto.ENUM, number=3, enum=gage_access_role.AccessRoleEnum.AccessRole, + ) + email_address = proto.Field(proto.STRING, number=4,) + creation_date_time = proto.Field(proto.STRING, number=5,) + invitation_status = proto.Field( + proto.ENUM, + number=6, + enum=access_invitation_status.AccessInvitationStatusEnum.AccessInvitationStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/customizer_attribute.py b/google/ads/googleads/v12/resources/types/customizer_attribute.py new file mode 100644 index 000000000..b5b2b49ee --- /dev/null +++ b/google/ads/googleads/v12/resources/types/customizer_attribute.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import customizer_attribute_status +from google.ads.googleads.v12.enums.types import customizer_attribute_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"CustomizerAttribute",}, +) + + +class CustomizerAttribute(proto.Message): + r"""A customizer attribute. + Use CustomerCustomizer, CampaignCustomizer, AdGroupCustomizer, + or AdGroupCriterionCustomizer to associate a customizer + attribute and set its value at the customer, campaign, ad group, + or ad group criterion level, respectively. + + Attributes: + resource_name (str): + Immutable. The resource name of the customizer attribute. + Customizer Attribute resource names have the form: + + ``customers/{customer_id}/customizerAttributes/{customizer_attribute_id}`` + id (int): + Output only. The ID of the customizer + attribute. + name (str): + Required. Immutable. Name of the customizer + attribute. Required. It must have a minimum + length of 1 and maximum length of 40. Name of an + enabled customizer attribute must be unique + (case insensitive). + type_ (google.ads.googleads.v12.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): + Immutable. The type of the customizer + attribute. + status (google.ads.googleads.v12.enums.types.CustomizerAttributeStatusEnum.CustomizerAttributeStatus): + Output only. The status of the customizer + attribute. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=customizer_attribute_type.CustomizerAttributeTypeEnum.CustomizerAttributeType, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=customizer_attribute_status.CustomizerAttributeStatusEnum.CustomizerAttributeStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/detail_placement_view.py b/google/ads/googleads/v12/resources/types/detail_placement_view.py new file mode 100644 index 000000000..464d8c803 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/detail_placement_view.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + placement_type as gage_placement_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DetailPlacementView",}, +) + + +class DetailPlacementView(proto.Message): + r"""A view with metrics aggregated by ad group and URL or YouTube + video. + + Attributes: + resource_name (str): + Output only. The resource name of the detail placement view. + Detail placement view resource names have the form: + + ``customers/{customer_id}/detailPlacementViews/{ad_group_id}~{base64_placement}`` + placement (str): + Output only. The automatic placement string + at detail level, e. g. website URL, mobile + application ID, or a YouTube video ID. + + This field is a member of `oneof`_ ``_placement``. + display_name (str): + Output only. The display name is URL name for + websites, YouTube video name for YouTube videos, + and translated mobile app name for mobile apps. + + This field is a member of `oneof`_ ``_display_name``. + group_placement_target_url (str): + Output only. URL of the group placement, for + example, domain, link to the mobile application + in app store, or a YouTube channel URL. + + This field is a member of `oneof`_ ``_group_placement_target_url``. + target_url (str): + Output only. URL of the placement, for + example, website, link to the mobile application + in app store, or a YouTube video URL. + + This field is a member of `oneof`_ ``_target_url``. + placement_type (google.ads.googleads.v12.enums.types.PlacementTypeEnum.PlacementType): + Output only. Type of the placement, for + example, Website, YouTube Video, and Mobile + Application. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + placement = proto.Field(proto.STRING, number=7, optional=True,) + display_name = proto.Field(proto.STRING, number=8, optional=True,) + group_placement_target_url = proto.Field( + proto.STRING, number=9, optional=True, + ) + target_url = proto.Field(proto.STRING, number=10, optional=True,) + placement_type = proto.Field( + proto.ENUM, + number=6, + enum=gage_placement_type.PlacementTypeEnum.PlacementType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/detailed_demographic.py b/google/ads/googleads/v12/resources/types/detailed_demographic.py new file mode 100644 index 000000000..0449309b0 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/detailed_demographic.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + criterion_category_availability, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DetailedDemographic",}, +) + + +class DetailedDemographic(proto.Message): + r"""A detailed demographic: a particular interest-based vertical + to be targeted to reach users based on long-term life facts. + + Attributes: + resource_name (str): + Output only. The resource name of the detailed demographic. + Detailed demographic resource names have the form: + + ``customers/{customer_id}/detailedDemographics/{detailed_demographic_id}`` + id (int): + Output only. The ID of the detailed + demographic. + name (str): + Output only. The name of the detailed + demographic. For example,"Highest Level of + Educational Attainment". + parent (str): + Output only. The parent of the detailed_demographic. + launched_to_all (bool): + Output only. True if the detailed demographic + is launched to all channels and locales. + availabilities (Sequence[google.ads.googleads.v12.common.types.CriterionCategoryAvailability]): + Output only. Availability information of the + detailed demographic. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + parent = proto.Field(proto.STRING, number=4,) + launched_to_all = proto.Field(proto.BOOL, number=5,) + availabilities = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=criterion_category_availability.CriterionCategoryAvailability, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/display_keyword_view.py b/google/ads/googleads/v12/resources/types/display_keyword_view.py new file mode 100644 index 000000000..f165284d9 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/display_keyword_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DisplayKeywordView",}, +) + + +class DisplayKeywordView(proto.Message): + r"""A display keyword view. + + Attributes: + resource_name (str): + Output only. The resource name of the display keyword view. + Display Keyword view resource names have the form: + + ``customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/distance_view.py b/google/ads/googleads/v12/resources/types/distance_view.py new file mode 100644 index 000000000..89c6d2e5d --- /dev/null +++ b/google/ads/googleads/v12/resources/types/distance_view.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + distance_bucket as gage_distance_bucket, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DistanceView",}, +) + + +class DistanceView(proto.Message): + r"""A distance view with metrics aggregated by the user's + distance from an advertiser's location extensions. Each + DistanceBucket includes all impressions that fall within its + distance and a single impression will contribute to the metrics + for all DistanceBuckets that include the user's distance. + + Attributes: + resource_name (str): + Output only. The resource name of the distance view. + Distance view resource names have the form: + + ``customers/{customer_id}/distanceViews/1~{distance_bucket}`` + distance_bucket (google.ads.googleads.v12.enums.types.DistanceBucketEnum.DistanceBucket): + Output only. Grouping of user distance from + location extensions. + metric_system (bool): + Output only. True if the DistanceBucket is + using the metric system, false otherwise. + + This field is a member of `oneof`_ ``_metric_system``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + distance_bucket = proto.Field( + proto.ENUM, + number=2, + enum=gage_distance_bucket.DistanceBucketEnum.DistanceBucket, + ) + metric_system = proto.Field(proto.BOOL, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/domain_category.py b/google/ads/googleads/v12/resources/types/domain_category.py new file mode 100644 index 000000000..0e474a9c3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/domain_category.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DomainCategory",}, +) + + +class DomainCategory(proto.Message): + r"""A category generated automatically by crawling a domain. If a + campaign uses the DynamicSearchAdsSetting, then domain + categories will be generated for the domain. The categories can + be targeted using WebpageConditionInfo. See: + https://support.google.com/google-ads/answer/2471185 + + Attributes: + resource_name (str): + Output only. The resource name of the domain category. + Domain category resource names have the form: + + ``customers/{customer_id}/domainCategories/{campaign_id}~{category_base64}~{language_code}`` + campaign (str): + Output only. The campaign this category is + recommended for. + + This field is a member of `oneof`_ ``_campaign``. + category (str): + Output only. Recommended category for the + website domain, for example, if you have a + website about electronics, the categories could + be "cameras", "televisions", etc. + + This field is a member of `oneof`_ ``_category``. + language_code (str): + Output only. The language code specifying the + language of the website, for example, "en" for + English. The language can be specified in the + DynamicSearchAdsSetting required for dynamic + search ads. This is the language of the pages + from your website that you want Google Ads to + find, create ads for, and match searches with. + + This field is a member of `oneof`_ ``_language_code``. + domain (str): + Output only. The domain for the website. The + domain can be specified in the + DynamicSearchAdsSetting required for dynamic + search ads. + + This field is a member of `oneof`_ ``_domain``. + coverage_fraction (float): + Output only. Fraction of pages on your site + that this category matches. + + This field is a member of `oneof`_ ``_coverage_fraction``. + category_rank (int): + Output only. The position of this category in + the set of categories. Lower numbers indicate a + better match for the domain. null indicates not + recommended. + + This field is a member of `oneof`_ ``_category_rank``. + has_children (bool): + Output only. Indicates whether this category + has sub-categories. + + This field is a member of `oneof`_ ``_has_children``. + recommended_cpc_bid_micros (int): + Output only. The recommended cost per click + for the category. + + This field is a member of `oneof`_ ``_recommended_cpc_bid_micros``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=10, optional=True,) + category = proto.Field(proto.STRING, number=11, optional=True,) + language_code = proto.Field(proto.STRING, number=12, optional=True,) + domain = proto.Field(proto.STRING, number=13, optional=True,) + coverage_fraction = proto.Field(proto.DOUBLE, number=14, optional=True,) + category_rank = proto.Field(proto.INT64, number=15, optional=True,) + has_children = proto.Field(proto.BOOL, number=16, optional=True,) + recommended_cpc_bid_micros = proto.Field( + proto.INT64, number=17, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/dynamic_search_ads_search_term_view.py b/google/ads/googleads/v12/resources/types/dynamic_search_ads_search_term_view.py new file mode 100644 index 000000000..01e70558a --- /dev/null +++ b/google/ads/googleads/v12/resources/types/dynamic_search_ads_search_term_view.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"DynamicSearchAdsSearchTermView",}, +) + + +class DynamicSearchAdsSearchTermView(proto.Message): + r"""A dynamic search ads search term view. + + Attributes: + resource_name (str): + Output only. The resource name of the dynamic search ads + search term view. Dynamic search ads search term view + resource names have the form: + + ``customers/{customer_id}/dynamicSearchAdsSearchTermViews/{ad_group_id}~{search_term_fingerprint}~{headline_fingerprint}~{landing_page_fingerprint}~{page_url_fingerprint}`` + search_term (str): + Output only. Search term + This field is read-only. + + This field is a member of `oneof`_ ``_search_term``. + headline (str): + Output only. The dynamically generated + headline of the Dynamic Search Ad. + This field is read-only. + + This field is a member of `oneof`_ ``_headline``. + landing_page (str): + Output only. The dynamically selected landing + page URL of the impression. + This field is read-only. + + This field is a member of `oneof`_ ``_landing_page``. + page_url (str): + Output only. The URL of page feed item served + for the impression. + This field is read-only. + + This field is a member of `oneof`_ ``_page_url``. + has_negative_keyword (bool): + Output only. True if query matches a negative + keyword. + This field is read-only. + + This field is a member of `oneof`_ ``_has_negative_keyword``. + has_matching_keyword (bool): + Output only. True if query is added to + targeted keywords. + This field is read-only. + + This field is a member of `oneof`_ ``_has_matching_keyword``. + has_negative_url (bool): + Output only. True if query matches a negative + url. + This field is read-only. + + This field is a member of `oneof`_ ``_has_negative_url``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + search_term = proto.Field(proto.STRING, number=9, optional=True,) + headline = proto.Field(proto.STRING, number=10, optional=True,) + landing_page = proto.Field(proto.STRING, number=11, optional=True,) + page_url = proto.Field(proto.STRING, number=12, optional=True,) + has_negative_keyword = proto.Field(proto.BOOL, number=13, optional=True,) + has_matching_keyword = proto.Field(proto.BOOL, number=14, optional=True,) + has_negative_url = proto.Field(proto.BOOL, number=15, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/expanded_landing_page_view.py b/google/ads/googleads/v12/resources/types/expanded_landing_page_view.py new file mode 100644 index 000000000..70a175c28 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/expanded_landing_page_view.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ExpandedLandingPageView",}, +) + + +class ExpandedLandingPageView(proto.Message): + r"""A landing page view with metrics aggregated at the expanded + final URL level. + + Attributes: + resource_name (str): + Output only. The resource name of the expanded landing page + view. Expanded landing page view resource names have the + form: + + ``customers/{customer_id}/expandedLandingPageViews/{expanded_final_url_fingerprint}`` + expanded_final_url (str): + Output only. The final URL that clicks are + directed to. + + This field is a member of `oneof`_ ``_expanded_final_url``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + expanded_final_url = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/experiment.py b/google/ads/googleads/v12/resources/types/experiment.py new file mode 100644 index 000000000..289b749b9 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/experiment.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import metric_goal +from google.ads.googleads.v12.enums.types import async_action_status +from google.ads.googleads.v12.enums.types import experiment_status +from google.ads.googleads.v12.enums.types import experiment_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Experiment",}, +) + + +class Experiment(proto.Message): + r"""A Google ads experiment for users to experiment changes on + multiple campaigns, compare the performance, and apply the + effective changes. + + Attributes: + resource_name (str): + Immutable. The resource name of the experiment. Experiment + resource names have the form: + + ``customers/{customer_id}/experiments/{experiment_id}`` + experiment_id (int): + Output only. The ID of the experiment. Read + only. + + This field is a member of `oneof`_ ``_experiment_id``. + name (str): + Required. The name of the experiment. It must + have a minimum length of 1 and maximum length of + 1024. It must be unique under a customer. + description (str): + The description of the experiment. It must + have a minimum length of 1 and maximum length of + 2048. + suffix (str): + For system managed experiments, the + advertiser must provide a suffix during + construction, in the setup stage before moving + to initiated. The suffix will be appended to the + in-design and experiment campaign names so that + the name is base campaign name + suffix. + type_ (google.ads.googleads.v12.enums.types.ExperimentTypeEnum.ExperimentType): + Required. The product/feature that uses this + experiment. + status (google.ads.googleads.v12.enums.types.ExperimentStatusEnum.ExperimentStatus): + The Advertiser-chosen status of this + experiment. + start_date (str): + Date when the experiment starts. By default, + the experiment starts now or on the campaign's + start date, whichever is later. If this field is + set, then the experiment starts at the beginning + of the specified date in the customer's time + zone. + + Format: YYYY-MM-DD + Example: 2019-03-14 + + This field is a member of `oneof`_ ``_start_date``. + end_date (str): + Date when the experiment ends. By default, + the experiment ends on the campaign's end date. + If this field is set, then the experiment ends + at the end of the specified date in the + customer's time zone. + Format: YYYY-MM-DD + Example: 2019-04-18 + + This field is a member of `oneof`_ ``_end_date``. + goals (Sequence[google.ads.googleads.v12.common.types.MetricGoal]): + The goals of this experiment. + long_running_operation (str): + Output only. The resource name of the + long-running operation that can be used to poll + for completion of experiment schedule or + promote. The most recent long running operation + is returned. + + This field is a member of `oneof`_ ``_long_running_operation``. + promote_status (google.ads.googleads.v12.enums.types.AsyncActionStatusEnum.AsyncActionStatus): + Output only. The status of the experiment + promotion process. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + experiment_id = proto.Field(proto.INT64, number=9, optional=True,) + name = proto.Field(proto.STRING, number=10,) + description = proto.Field(proto.STRING, number=11,) + suffix = proto.Field(proto.STRING, number=12,) + type_ = proto.Field( + proto.ENUM, + number=13, + enum=experiment_type.ExperimentTypeEnum.ExperimentType, + ) + status = proto.Field( + proto.ENUM, + number=14, + enum=experiment_status.ExperimentStatusEnum.ExperimentStatus, + ) + start_date = proto.Field(proto.STRING, number=15, optional=True,) + end_date = proto.Field(proto.STRING, number=16, optional=True,) + goals = proto.RepeatedField( + proto.MESSAGE, number=17, message=metric_goal.MetricGoal, + ) + long_running_operation = proto.Field( + proto.STRING, number=18, optional=True, + ) + promote_status = proto.Field( + proto.ENUM, + number=19, + enum=async_action_status.AsyncActionStatusEnum.AsyncActionStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/experiment_arm.py b/google/ads/googleads/v12/resources/types/experiment_arm.py new file mode 100644 index 000000000..eb1b12a55 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/experiment_arm.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ExperimentArm",}, +) + + +class ExperimentArm(proto.Message): + r"""A Google ads experiment for users to experiment changes on + multiple campaigns, compare the performance, and apply the + effective changes. + + Attributes: + resource_name (str): + Immutable. The resource name of the experiment arm. + Experiment arm resource names have the form: + + ``customers/{customer_id}/experimentArms/{TrialArm.trial_id}~{TrialArm.trial_arm_id}`` + experiment (str): + Immutable. The experiment to which the + ExperimentArm belongs. + name (str): + Required. The name of the experiment arm. It + must have a minimum length of 1 and maximum + length of 1024. It must be unique under an + experiment. + control (bool): + Whether this arm is a control arm. A control + arm is the arm against which the other arms are + compared. + traffic_split (int): + Traffic split of the trial arm. The value + should be between 1 and 100 and must total 100 + between the two trial arms. + campaigns (Sequence[str]): + List of campaigns in the trial arm. The max + length is one. + in_design_campaigns (Sequence[str]): + Output only. The in design campaigns in the + treatment experiment arm. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + experiment = proto.Field(proto.STRING, number=8,) + name = proto.Field(proto.STRING, number=3,) + control = proto.Field(proto.BOOL, number=4,) + traffic_split = proto.Field(proto.INT64, number=5,) + campaigns = proto.RepeatedField(proto.STRING, number=6,) + in_design_campaigns = proto.RepeatedField(proto.STRING, number=7,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/extension_feed_item.py b/google/ads/googleads/v12/resources/types/extension_feed_item.py new file mode 100644 index 000000000..57392af7e --- /dev/null +++ b/google/ads/googleads/v12/resources/types/extension_feed_item.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.common.types import extensions +from google.ads.googleads.v12.enums.types import ( + extension_type as gage_extension_type, +) +from google.ads.googleads.v12.enums.types import feed_item_status +from google.ads.googleads.v12.enums.types import feed_item_target_device + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ExtensionFeedItem",}, +) + + +class ExtensionFeedItem(proto.Message): + r"""An extension feed item. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the extension feed item. + Extension feed item resource names have the form: + + ``customers/{customer_id}/extensionFeedItems/{feed_item_id}`` + id (int): + Output only. The ID of this feed item. + Read-only. + + This field is a member of `oneof`_ ``_id``. + extension_type (google.ads.googleads.v12.enums.types.ExtensionTypeEnum.ExtensionType): + Output only. The extension type of the + extension feed item. This field is read-only. + start_date_time (str): + Start time in which this feed item is + effective and can begin serving. The time is in + the customer's time zone. The format is + "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_start_date_time``. + end_date_time (str): + End time in which this feed item is no longer + effective and will stop serving. The time is in + the customer's time zone. The format is + "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_end_date_time``. + ad_schedules (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + List of non-overlapping schedules specifying + all time intervals for which the feed item may + serve. There can be a maximum of 6 schedules per + day. + device (google.ads.googleads.v12.enums.types.FeedItemTargetDeviceEnum.FeedItemTargetDevice): + The targeted device. + targeted_geo_target_constant (str): + The targeted geo target constant. + + This field is a member of `oneof`_ ``_targeted_geo_target_constant``. + targeted_keyword (google.ads.googleads.v12.common.types.KeywordInfo): + The targeted keyword. + status (google.ads.googleads.v12.enums.types.FeedItemStatusEnum.FeedItemStatus): + Output only. Status of the feed item. + This field is read-only. + sitelink_feed_item (google.ads.googleads.v12.common.types.SitelinkFeedItem): + Sitelink extension. + + This field is a member of `oneof`_ ``extension``. + structured_snippet_feed_item (google.ads.googleads.v12.common.types.StructuredSnippetFeedItem): + Structured snippet extension. + + This field is a member of `oneof`_ ``extension``. + app_feed_item (google.ads.googleads.v12.common.types.AppFeedItem): + App extension. + + This field is a member of `oneof`_ ``extension``. + call_feed_item (google.ads.googleads.v12.common.types.CallFeedItem): + Call extension. + + This field is a member of `oneof`_ ``extension``. + callout_feed_item (google.ads.googleads.v12.common.types.CalloutFeedItem): + Callout extension. + + This field is a member of `oneof`_ ``extension``. + text_message_feed_item (google.ads.googleads.v12.common.types.TextMessageFeedItem): + Text message extension. + + This field is a member of `oneof`_ ``extension``. + price_feed_item (google.ads.googleads.v12.common.types.PriceFeedItem): + Price extension. + + This field is a member of `oneof`_ ``extension``. + promotion_feed_item (google.ads.googleads.v12.common.types.PromotionFeedItem): + Promotion extension. + + This field is a member of `oneof`_ ``extension``. + location_feed_item (google.ads.googleads.v12.common.types.LocationFeedItem): + Output only. Location extension. Locations + are synced from a Business Profile into a feed. + This field is read-only. + + This field is a member of `oneof`_ ``extension``. + affiliate_location_feed_item (google.ads.googleads.v12.common.types.AffiliateLocationFeedItem): + Output only. Affiliate location extension. + Feed locations are populated by Google Ads based + on a chain ID. This field is read-only. + + This field is a member of `oneof`_ ``extension``. + hotel_callout_feed_item (google.ads.googleads.v12.common.types.HotelCalloutFeedItem): + Hotel Callout extension. + + This field is a member of `oneof`_ ``extension``. + image_feed_item (google.ads.googleads.v12.common.types.ImageFeedItem): + Immutable. Advertiser provided image + extension. + + This field is a member of `oneof`_ ``extension``. + targeted_campaign (str): + The targeted campaign. + + This field is a member of `oneof`_ ``serving_resource_targeting``. + targeted_ad_group (str): + The targeted ad group. + + This field is a member of `oneof`_ ``serving_resource_targeting``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=25, optional=True,) + extension_type = proto.Field( + proto.ENUM, + number=13, + enum=gage_extension_type.ExtensionTypeEnum.ExtensionType, + ) + start_date_time = proto.Field(proto.STRING, number=26, optional=True,) + end_date_time = proto.Field(proto.STRING, number=27, optional=True,) + ad_schedules = proto.RepeatedField( + proto.MESSAGE, number=16, message=criteria.AdScheduleInfo, + ) + device = proto.Field( + proto.ENUM, + number=17, + enum=feed_item_target_device.FeedItemTargetDeviceEnum.FeedItemTargetDevice, + ) + targeted_geo_target_constant = proto.Field( + proto.STRING, number=30, optional=True, + ) + targeted_keyword = proto.Field( + proto.MESSAGE, number=22, message=criteria.KeywordInfo, + ) + status = proto.Field( + proto.ENUM, + number=4, + enum=feed_item_status.FeedItemStatusEnum.FeedItemStatus, + ) + sitelink_feed_item = proto.Field( + proto.MESSAGE, + number=2, + oneof="extension", + message=extensions.SitelinkFeedItem, + ) + structured_snippet_feed_item = proto.Field( + proto.MESSAGE, + number=3, + oneof="extension", + message=extensions.StructuredSnippetFeedItem, + ) + app_feed_item = proto.Field( + proto.MESSAGE, + number=7, + oneof="extension", + message=extensions.AppFeedItem, + ) + call_feed_item = proto.Field( + proto.MESSAGE, + number=8, + oneof="extension", + message=extensions.CallFeedItem, + ) + callout_feed_item = proto.Field( + proto.MESSAGE, + number=9, + oneof="extension", + message=extensions.CalloutFeedItem, + ) + text_message_feed_item = proto.Field( + proto.MESSAGE, + number=10, + oneof="extension", + message=extensions.TextMessageFeedItem, + ) + price_feed_item = proto.Field( + proto.MESSAGE, + number=11, + oneof="extension", + message=extensions.PriceFeedItem, + ) + promotion_feed_item = proto.Field( + proto.MESSAGE, + number=12, + oneof="extension", + message=extensions.PromotionFeedItem, + ) + location_feed_item = proto.Field( + proto.MESSAGE, + number=14, + oneof="extension", + message=extensions.LocationFeedItem, + ) + affiliate_location_feed_item = proto.Field( + proto.MESSAGE, + number=15, + oneof="extension", + message=extensions.AffiliateLocationFeedItem, + ) + hotel_callout_feed_item = proto.Field( + proto.MESSAGE, + number=23, + oneof="extension", + message=extensions.HotelCalloutFeedItem, + ) + image_feed_item = proto.Field( + proto.MESSAGE, + number=31, + oneof="extension", + message=extensions.ImageFeedItem, + ) + targeted_campaign = proto.Field( + proto.STRING, number=28, oneof="serving_resource_targeting", + ) + targeted_ad_group = proto.Field( + proto.STRING, number=29, oneof="serving_resource_targeting", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed.py b/google/ads/googleads/v12/resources/types/feed.py new file mode 100644 index 000000000..61a9b3326 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + affiliate_location_feed_relationship_type, +) +from google.ads.googleads.v12.enums.types import feed_attribute_type +from google.ads.googleads.v12.enums.types import feed_origin +from google.ads.googleads.v12.enums.types import feed_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Feed", "FeedAttribute", "FeedAttributeOperation",}, +) + + +class Feed(proto.Message): + r"""A feed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the feed. Feed resource + names have the form: + + ``customers/{customer_id}/feeds/{feed_id}`` + id (int): + Output only. The ID of the feed. + This field is read-only. + + This field is a member of `oneof`_ ``_id``. + name (str): + Immutable. Name of the feed. Required. + + This field is a member of `oneof`_ ``_name``. + attributes (Sequence[google.ads.googleads.v12.resources.types.FeedAttribute]): + The Feed's attributes. Required on CREATE, unless + system_feed_generation_data is provided, in which case + Google Ads will update the feed with the correct attributes. + Disallowed on UPDATE. Use attribute_operations to add new + attributes. + attribute_operations (Sequence[google.ads.googleads.v12.resources.types.FeedAttributeOperation]): + The list of operations changing the feed + attributes. Attributes can only be added, not + removed. + origin (google.ads.googleads.v12.enums.types.FeedOriginEnum.FeedOrigin): + Immutable. Specifies who manages the + FeedAttributes for the Feed. + status (google.ads.googleads.v12.enums.types.FeedStatusEnum.FeedStatus): + Output only. Status of the feed. + This field is read-only. + places_location_feed_data (google.ads.googleads.v12.resources.types.Feed.PlacesLocationFeedData): + Data used to configure a location feed + populated from Business Profile. + + This field is a member of `oneof`_ ``system_feed_generation_data``. + affiliate_location_feed_data (google.ads.googleads.v12.resources.types.Feed.AffiliateLocationFeedData): + Data used to configure an affiliate location + feed populated with the specified chains. + + This field is a member of `oneof`_ ``system_feed_generation_data``. + """ + + class PlacesLocationFeedData(proto.Message): + r"""Data used to configure a location feed populated from + Business Profile. + + Attributes: + oauth_info (google.ads.googleads.v12.resources.types.Feed.PlacesLocationFeedData.OAuthInfo): + Immutable. Required authentication token + (from OAuth API) for the email. This field can + only be specified in a create request. All its + subfields are not selectable. + email_address (str): + Email address of a Business Profile or email + address of a manager of the Business Profile. + Required. + + This field is a member of `oneof`_ ``_email_address``. + business_account_id (str): + Plus page ID of the managed business whose locations should + be used. If this field is not set, then all businesses + accessible by the user (specified by email_address) are + used. This field is mutate-only and is not selectable. + business_name_filter (str): + Used to filter Business Profile listings by business name. + If business_name_filter is set, only listings with a + matching business name are candidates to be sync'd into + FeedItems. + + This field is a member of `oneof`_ ``_business_name_filter``. + category_filters (Sequence[str]): + Used to filter Business Profile listings by categories. If + entries exist in category_filters, only listings that belong + to any of the categories are candidates to be sync'd into + FeedItems. If no entries exist in category_filters, then all + listings are candidates for syncing. + label_filters (Sequence[str]): + Used to filter Business Profile listings by labels. If + entries exist in label_filters, only listings that has any + of the labels set are candidates to be synchronized into + FeedItems. If no entries exist in label_filters, then all + listings are candidates for syncing. + """ + + class OAuthInfo(proto.Message): + r"""Data used for authorization using OAuth. + + Attributes: + http_method (str): + The HTTP method used to obtain authorization. + + This field is a member of `oneof`_ ``_http_method``. + http_request_url (str): + The HTTP request URL used to obtain + authorization. + + This field is a member of `oneof`_ ``_http_request_url``. + http_authorization_header (str): + The HTTP authorization header used to obtain + authorization. + + This field is a member of `oneof`_ ``_http_authorization_header``. + """ + + http_method = proto.Field(proto.STRING, number=4, optional=True,) + http_request_url = proto.Field( + proto.STRING, number=5, optional=True, + ) + http_authorization_header = proto.Field( + proto.STRING, number=6, optional=True, + ) + + oauth_info = proto.Field( + proto.MESSAGE, + number=1, + message="Feed.PlacesLocationFeedData.OAuthInfo", + ) + email_address = proto.Field(proto.STRING, number=7, optional=True,) + business_account_id = proto.Field(proto.STRING, number=8,) + business_name_filter = proto.Field( + proto.STRING, number=9, optional=True, + ) + category_filters = proto.RepeatedField(proto.STRING, number=11,) + label_filters = proto.RepeatedField(proto.STRING, number=12,) + + class AffiliateLocationFeedData(proto.Message): + r"""Data used to configure an affiliate location feed populated + with the specified chains. + + Attributes: + chain_ids (Sequence[int]): + The list of chains that the affiliate + location feed will sync the locations from. + relationship_type (google.ads.googleads.v12.enums.types.AffiliateLocationFeedRelationshipTypeEnum.AffiliateLocationFeedRelationshipType): + The relationship the chains have with the + advertiser. + """ + + chain_ids = proto.RepeatedField(proto.INT64, number=3,) + relationship_type = proto.Field( + proto.ENUM, + number=2, + enum=affiliate_location_feed_relationship_type.AffiliateLocationFeedRelationshipTypeEnum.AffiliateLocationFeedRelationshipType, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=11, optional=True,) + name = proto.Field(proto.STRING, number=12, optional=True,) + attributes = proto.RepeatedField( + proto.MESSAGE, number=4, message="FeedAttribute", + ) + attribute_operations = proto.RepeatedField( + proto.MESSAGE, number=9, message="FeedAttributeOperation", + ) + origin = proto.Field( + proto.ENUM, number=5, enum=feed_origin.FeedOriginEnum.FeedOrigin, + ) + status = proto.Field( + proto.ENUM, number=8, enum=feed_status.FeedStatusEnum.FeedStatus, + ) + places_location_feed_data = proto.Field( + proto.MESSAGE, + number=6, + oneof="system_feed_generation_data", + message=PlacesLocationFeedData, + ) + affiliate_location_feed_data = proto.Field( + proto.MESSAGE, + number=7, + oneof="system_feed_generation_data", + message=AffiliateLocationFeedData, + ) + + +class FeedAttribute(proto.Message): + r"""FeedAttributes define the types of data expected to be + present in a Feed. A single FeedAttribute specifies the expected + type of the FeedItemAttributes with the same FeedAttributeId. + Optionally, a FeedAttribute can be marked as being part of a + FeedItem's unique key. + + Attributes: + id (int): + ID of the attribute. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the attribute. Required. + + This field is a member of `oneof`_ ``_name``. + type_ (google.ads.googleads.v12.enums.types.FeedAttributeTypeEnum.FeedAttributeType): + Data type for feed attribute. Required. + is_part_of_key (bool): + Indicates that data corresponding to this attribute is part + of a FeedItem's unique key. It defaults to false if it is + unspecified. Note that a unique key is not required in a + Feed's schema, in which case the FeedItems must be + referenced by their feed_item_id. + + This field is a member of `oneof`_ ``_is_part_of_key``. + """ + + id = proto.Field(proto.INT64, number=5, optional=True,) + name = proto.Field(proto.STRING, number=6, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=feed_attribute_type.FeedAttributeTypeEnum.FeedAttributeType, + ) + is_part_of_key = proto.Field(proto.BOOL, number=7, optional=True,) + + +class FeedAttributeOperation(proto.Message): + r"""Operation to be performed on a feed attribute list in a + mutate. + + Attributes: + operator (google.ads.googleads.v12.resources.types.FeedAttributeOperation.Operator): + Output only. Type of list operation to + perform. + value (google.ads.googleads.v12.resources.types.FeedAttribute): + Output only. The feed attribute being added + to the list. + """ + + class Operator(proto.Enum): + r"""The operator.""" + UNSPECIFIED = 0 + UNKNOWN = 1 + ADD = 2 + + operator = proto.Field(proto.ENUM, number=1, enum=Operator,) + value = proto.Field(proto.MESSAGE, number=2, message="FeedAttribute",) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_item.py b/google/ads/googleads/v12/resources/types/feed_item.py new file mode 100644 index 000000000..2dc15b261 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_item.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import custom_parameter +from google.ads.googleads.v12.common.types import feed_common +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import ( + feed_item_quality_approval_status, +) +from google.ads.googleads.v12.enums.types import ( + feed_item_quality_disapproval_reason, +) +from google.ads.googleads.v12.enums.types import feed_item_status +from google.ads.googleads.v12.enums.types import feed_item_validation_status +from google.ads.googleads.v12.enums.types import ( + geo_targeting_restriction as gage_geo_targeting_restriction, +) +from google.ads.googleads.v12.enums.types import placeholder_type +from google.ads.googleads.v12.enums.types import policy_approval_status +from google.ads.googleads.v12.enums.types import policy_review_status +from google.ads.googleads.v12.errors.types import feed_item_validation_error + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={ + "FeedItem", + "FeedItemAttributeValue", + "FeedItemPlaceholderPolicyInfo", + "FeedItemValidationError", + }, +) + + +class FeedItem(proto.Message): + r"""A feed item. + + Attributes: + resource_name (str): + Immutable. The resource name of the feed item. Feed item + resource names have the form: + + ``customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}`` + feed (str): + Immutable. The feed to which this feed item + belongs. + + This field is a member of `oneof`_ ``_feed``. + id (int): + Output only. The ID of this feed item. + + This field is a member of `oneof`_ ``_id``. + start_date_time (str): + Start time in which this feed item is + effective and can begin serving. The time is in + the customer's time zone. The format is + "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_start_date_time``. + end_date_time (str): + End time in which this feed item is no longer + effective and will stop serving. The time is in + the customer's time zone. The format is + "YYYY-MM-DD HH:MM:SS". + Examples: "2018-03-05 09:15:00" or "2018-02-01 + 14:34:30". + + This field is a member of `oneof`_ ``_end_date_time``. + attribute_values (Sequence[google.ads.googleads.v12.resources.types.FeedItemAttributeValue]): + The feed item's attribute values. + geo_targeting_restriction (google.ads.googleads.v12.enums.types.GeoTargetingRestrictionEnum.GeoTargetingRestriction): + Geo targeting restriction specifies the type + of location that can be used for targeting. + url_custom_parameters (Sequence[google.ads.googleads.v12.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + status (google.ads.googleads.v12.enums.types.FeedItemStatusEnum.FeedItemStatus): + Output only. Status of the feed item. + This field is read-only. + policy_infos (Sequence[google.ads.googleads.v12.resources.types.FeedItemPlaceholderPolicyInfo]): + Output only. List of info about a feed item's + validation and approval state for active feed + mappings. There will be an entry in the list for + each type of feed mapping associated with the + feed, for example, a feed with a sitelink and a + call feed mapping would cause every feed item + associated with that feed to have an entry in + this list for both sitelink and call. This field + is read-only. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=11, optional=True,) + id = proto.Field(proto.INT64, number=12, optional=True,) + start_date_time = proto.Field(proto.STRING, number=13, optional=True,) + end_date_time = proto.Field(proto.STRING, number=14, optional=True,) + attribute_values = proto.RepeatedField( + proto.MESSAGE, number=6, message="FeedItemAttributeValue", + ) + geo_targeting_restriction = proto.Field( + proto.ENUM, + number=7, + enum=gage_geo_targeting_restriction.GeoTargetingRestrictionEnum.GeoTargetingRestriction, + ) + url_custom_parameters = proto.RepeatedField( + proto.MESSAGE, number=8, message=custom_parameter.CustomParameter, + ) + status = proto.Field( + proto.ENUM, + number=9, + enum=feed_item_status.FeedItemStatusEnum.FeedItemStatus, + ) + policy_infos = proto.RepeatedField( + proto.MESSAGE, number=10, message="FeedItemPlaceholderPolicyInfo", + ) + + +class FeedItemAttributeValue(proto.Message): + r"""A feed item attribute value. + + Attributes: + feed_attribute_id (int): + Id of the feed attribute for which the value + is associated with. + + This field is a member of `oneof`_ ``_feed_attribute_id``. + integer_value (int): + Int64 value. Should be set if feed_attribute_id refers to a + feed attribute of type INT64. + + This field is a member of `oneof`_ ``_integer_value``. + boolean_value (bool): + Bool value. Should be set if feed_attribute_id refers to a + feed attribute of type BOOLEAN. + + This field is a member of `oneof`_ ``_boolean_value``. + string_value (str): + String value. Should be set if feed_attribute_id refers to a + feed attribute of type STRING, URL or DATE_TIME. For STRING + the maximum length is 1500 characters. For URL the maximum + length is 2076 characters. For DATE_TIME the string must be + in the format "YYYYMMDD HHMMSS". + + This field is a member of `oneof`_ ``_string_value``. + double_value (float): + Double value. Should be set if feed_attribute_id refers to a + feed attribute of type DOUBLE. + + This field is a member of `oneof`_ ``_double_value``. + price_value (google.ads.googleads.v12.common.types.Money): + Price value. Should be set if feed_attribute_id refers to a + feed attribute of type PRICE. + integer_values (Sequence[int]): + Repeated int64 value. Should be set if feed_attribute_id + refers to a feed attribute of type INT64_LIST. + boolean_values (Sequence[bool]): + Repeated bool value. Should be set if feed_attribute_id + refers to a feed attribute of type BOOLEAN_LIST. + string_values (Sequence[str]): + Repeated string value. Should be set if feed_attribute_id + refers to a feed attribute of type STRING_LIST, URL_LIST or + DATE_TIME_LIST. For STRING_LIST and URL_LIST the total size + of the list in bytes may not exceed 3000. For DATE_TIME_LIST + the number of elements may not exceed 200. + + For STRING_LIST the maximum length of each string element is + 1500 characters. For URL_LIST the maximum length is 2076 + characters. For DATE_TIME the format of the string must be + the same as start and end time for the feed item. + double_values (Sequence[float]): + Repeated double value. Should be set if feed_attribute_id + refers to a feed attribute of type DOUBLE_LIST. + """ + + feed_attribute_id = proto.Field(proto.INT64, number=11, optional=True,) + integer_value = proto.Field(proto.INT64, number=12, optional=True,) + boolean_value = proto.Field(proto.BOOL, number=13, optional=True,) + string_value = proto.Field(proto.STRING, number=14, optional=True,) + double_value = proto.Field(proto.DOUBLE, number=15, optional=True,) + price_value = proto.Field( + proto.MESSAGE, number=6, message=feed_common.Money, + ) + integer_values = proto.RepeatedField(proto.INT64, number=16,) + boolean_values = proto.RepeatedField(proto.BOOL, number=17,) + string_values = proto.RepeatedField(proto.STRING, number=18,) + double_values = proto.RepeatedField(proto.DOUBLE, number=19,) + + +class FeedItemPlaceholderPolicyInfo(proto.Message): + r"""Policy, validation, and quality approval info for a feed item + for the specified placeholder type. + + Attributes: + placeholder_type_enum (google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType): + Output only. The placeholder type. + feed_mapping_resource_name (str): + Output only. The FeedMapping that contains + the placeholder type. + + This field is a member of `oneof`_ ``_feed_mapping_resource_name``. + review_status (google.ads.googleads.v12.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + Output only. Where the placeholder type is in + the review process. + approval_status (google.ads.googleads.v12.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + Output only. The overall approval status of + the placeholder type, calculated based on the + status of its individual policy topic entries. + policy_topic_entries (Sequence[google.ads.googleads.v12.common.types.PolicyTopicEntry]): + Output only. The list of policy findings for + the placeholder type. + validation_status (google.ads.googleads.v12.enums.types.FeedItemValidationStatusEnum.FeedItemValidationStatus): + Output only. The validation status of the + palceholder type. + validation_errors (Sequence[google.ads.googleads.v12.resources.types.FeedItemValidationError]): + Output only. List of placeholder type + validation errors. + quality_approval_status (google.ads.googleads.v12.enums.types.FeedItemQualityApprovalStatusEnum.FeedItemQualityApprovalStatus): + Output only. Placeholder type quality + evaluation approval status. + quality_disapproval_reasons (Sequence[google.ads.googleads.v12.enums.types.FeedItemQualityDisapprovalReasonEnum.FeedItemQualityDisapprovalReason]): + Output only. List of placeholder type quality + evaluation disapproval reasons. + """ + + placeholder_type_enum = proto.Field( + proto.ENUM, + number=10, + enum=placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + feed_mapping_resource_name = proto.Field( + proto.STRING, number=11, optional=True, + ) + review_status = proto.Field( + proto.ENUM, + number=3, + enum=policy_review_status.PolicyReviewStatusEnum.PolicyReviewStatus, + ) + approval_status = proto.Field( + proto.ENUM, + number=4, + enum=policy_approval_status.PolicyApprovalStatusEnum.PolicyApprovalStatus, + ) + policy_topic_entries = proto.RepeatedField( + proto.MESSAGE, number=5, message=policy.PolicyTopicEntry, + ) + validation_status = proto.Field( + proto.ENUM, + number=6, + enum=feed_item_validation_status.FeedItemValidationStatusEnum.FeedItemValidationStatus, + ) + validation_errors = proto.RepeatedField( + proto.MESSAGE, number=7, message="FeedItemValidationError", + ) + quality_approval_status = proto.Field( + proto.ENUM, + number=8, + enum=feed_item_quality_approval_status.FeedItemQualityApprovalStatusEnum.FeedItemQualityApprovalStatus, + ) + quality_disapproval_reasons = proto.RepeatedField( + proto.ENUM, + number=9, + enum=feed_item_quality_disapproval_reason.FeedItemQualityDisapprovalReasonEnum.FeedItemQualityDisapprovalReason, + ) + + +class FeedItemValidationError(proto.Message): + r"""Stores a validation error and the set of offending feed + attributes which together are responsible for causing a feed + item validation error. + + Attributes: + validation_error (google.ads.googleads.v12.errors.types.FeedItemValidationErrorEnum.FeedItemValidationError): + Output only. Error code indicating what + validation error was triggered. The description + of the error can be found in the 'description' + field. + description (str): + Output only. The description of the + validation error. + + This field is a member of `oneof`_ ``_description``. + feed_attribute_ids (Sequence[int]): + Output only. Set of feed attributes in the + feed item flagged during validation. If empty, + no specific feed attributes can be associated + with the error (for example, error across the + entire feed item). + extra_info (str): + Output only. Any extra information related to this error + which is not captured by validation_error and + feed_attribute_id (for example, placeholder field IDs when + feed_attribute_id is not mapped). Note that extra_info is + not localized. + + This field is a member of `oneof`_ ``_extra_info``. + """ + + validation_error = proto.Field( + proto.ENUM, + number=1, + enum=feed_item_validation_error.FeedItemValidationErrorEnum.FeedItemValidationError, + ) + description = proto.Field(proto.STRING, number=6, optional=True,) + feed_attribute_ids = proto.RepeatedField(proto.INT64, number=7,) + extra_info = proto.Field(proto.STRING, number=8, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_item_set.py b/google/ads/googleads/v12/resources/types/feed_item_set.py new file mode 100644 index 000000000..bb84c1db1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_item_set.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + feed_item_set_filter_type_infos, +) +from google.ads.googleads.v12.enums.types import feed_item_set_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSet",}, +) + + +class FeedItemSet(proto.Message): + r"""Represents a set of feed items. The set can be used and + shared among certain feed item features. For instance, the set + can be referenced within the matching functions of CustomerFeed, + CampaignFeed, and AdGroupFeed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the feed item set. Feed item + set resource names have the form: + ``customers/{customer_id}/feedItemSets/{feed_id}~{feed_item_set_id}`` + feed (str): + Immutable. The resource name of the feed + containing the feed items in the set. Immutable. + Required. + feed_item_set_id (int): + Output only. ID of the set. + display_name (str): + Name of the set. Must be unique within the + account. + status (google.ads.googleads.v12.enums.types.FeedItemSetStatusEnum.FeedItemSetStatus): + Output only. Status of the feed item set. + This field is read-only. + dynamic_location_set_filter (google.ads.googleads.v12.common.types.DynamicLocationSetFilter): + Filter for dynamic location set. + It is only used for sets of locations. + + This field is a member of `oneof`_ ``dynamic_set_filter``. + dynamic_affiliate_location_set_filter (google.ads.googleads.v12.common.types.DynamicAffiliateLocationSetFilter): + Filter for dynamic affiliate location set. + This field doesn't apply generally to feed item + sets. It is only used for sets of affiliate + locations. + + This field is a member of `oneof`_ ``dynamic_set_filter``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=2,) + feed_item_set_id = proto.Field(proto.INT64, number=3,) + display_name = proto.Field(proto.STRING, number=4,) + status = proto.Field( + proto.ENUM, + number=8, + enum=feed_item_set_status.FeedItemSetStatusEnum.FeedItemSetStatus, + ) + dynamic_location_set_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="dynamic_set_filter", + message=feed_item_set_filter_type_infos.DynamicLocationSetFilter, + ) + dynamic_affiliate_location_set_filter = proto.Field( + proto.MESSAGE, + number=6, + oneof="dynamic_set_filter", + message=feed_item_set_filter_type_infos.DynamicAffiliateLocationSetFilter, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_item_set_link.py b/google/ads/googleads/v12/resources/types/feed_item_set_link.py new file mode 100644 index 000000000..6d4b51bb3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_item_set_link.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"FeedItemSetLink",}, +) + + +class FeedItemSetLink(proto.Message): + r"""Represents a link between a FeedItem and a FeedItemSet. + + Attributes: + resource_name (str): + Immutable. The resource name of the feed item set link. Feed + item set link resource names have the form: + ``customers/{customer_id}/feedItemSetLinks/{feed_id}~{feed_item_set_id}~{feed_item_id}`` + feed_item (str): + Immutable. The linked FeedItem. + feed_item_set (str): + Immutable. The linked FeedItemSet. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed_item = proto.Field(proto.STRING, number=2,) + feed_item_set = proto.Field(proto.STRING, number=3,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_item_target.py b/google/ads/googleads/v12/resources/types/feed_item_target.py new file mode 100644 index 000000000..4e9b4adc0 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_item_target.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import feed_item_target_device +from google.ads.googleads.v12.enums.types import feed_item_target_status +from google.ads.googleads.v12.enums.types import ( + feed_item_target_type as gage_feed_item_target_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"FeedItemTarget",}, +) + + +class FeedItemTarget(proto.Message): + r"""A feed item target. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the feed item target. Feed + item target resource names have the form: + ``customers/{customer_id}/feedItemTargets/{feed_id}~{feed_item_id}~{feed_item_target_type}~{feed_item_target_id}`` + feed_item (str): + Immutable. The feed item to which this feed + item target belongs. + + This field is a member of `oneof`_ ``_feed_item``. + feed_item_target_type (google.ads.googleads.v12.enums.types.FeedItemTargetTypeEnum.FeedItemTargetType): + Output only. The target type of this feed + item target. This field is read-only. + feed_item_target_id (int): + Output only. The ID of the targeted resource. + This field is read-only. + + This field is a member of `oneof`_ ``_feed_item_target_id``. + status (google.ads.googleads.v12.enums.types.FeedItemTargetStatusEnum.FeedItemTargetStatus): + Output only. Status of the feed item target. + This field is read-only. + campaign (str): + Immutable. The targeted campaign. + + This field is a member of `oneof`_ ``target``. + ad_group (str): + Immutable. The targeted ad group. + + This field is a member of `oneof`_ ``target``. + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Immutable. The targeted keyword. + + This field is a member of `oneof`_ ``target``. + geo_target_constant (str): + Immutable. The targeted geo target constant + resource name. + + This field is a member of `oneof`_ ``target``. + device (google.ads.googleads.v12.enums.types.FeedItemTargetDeviceEnum.FeedItemTargetDevice): + Immutable. The targeted device. + + This field is a member of `oneof`_ ``target``. + ad_schedule (google.ads.googleads.v12.common.types.AdScheduleInfo): + Immutable. The targeted schedule. + + This field is a member of `oneof`_ ``target``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed_item = proto.Field(proto.STRING, number=12, optional=True,) + feed_item_target_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_feed_item_target_type.FeedItemTargetTypeEnum.FeedItemTargetType, + ) + feed_item_target_id = proto.Field(proto.INT64, number=13, optional=True,) + status = proto.Field( + proto.ENUM, + number=11, + enum=feed_item_target_status.FeedItemTargetStatusEnum.FeedItemTargetStatus, + ) + campaign = proto.Field(proto.STRING, number=14, oneof="target",) + ad_group = proto.Field(proto.STRING, number=15, oneof="target",) + keyword = proto.Field( + proto.MESSAGE, number=7, oneof="target", message=criteria.KeywordInfo, + ) + geo_target_constant = proto.Field(proto.STRING, number=16, oneof="target",) + device = proto.Field( + proto.ENUM, + number=9, + oneof="target", + enum=feed_item_target_device.FeedItemTargetDeviceEnum.FeedItemTargetDevice, + ) + ad_schedule = proto.Field( + proto.MESSAGE, + number=10, + oneof="target", + message=criteria.AdScheduleInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_mapping.py b/google/ads/googleads/v12/resources/types/feed_mapping.py new file mode 100644 index 000000000..1f06c5c38 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_mapping.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ad_customizer_placeholder_field +from google.ads.googleads.v12.enums.types import ( + affiliate_location_placeholder_field, +) +from google.ads.googleads.v12.enums.types import app_placeholder_field +from google.ads.googleads.v12.enums.types import call_placeholder_field +from google.ads.googleads.v12.enums.types import callout_placeholder_field +from google.ads.googleads.v12.enums.types import custom_placeholder_field +from google.ads.googleads.v12.enums.types import dsa_page_feed_criterion_field +from google.ads.googleads.v12.enums.types import education_placeholder_field +from google.ads.googleads.v12.enums.types import feed_mapping_criterion_type +from google.ads.googleads.v12.enums.types import feed_mapping_status +from google.ads.googleads.v12.enums.types import flight_placeholder_field +from google.ads.googleads.v12.enums.types import hotel_placeholder_field +from google.ads.googleads.v12.enums.types import image_placeholder_field +from google.ads.googleads.v12.enums.types import job_placeholder_field +from google.ads.googleads.v12.enums.types import local_placeholder_field +from google.ads.googleads.v12.enums.types import ( + location_extension_targeting_criterion_field, +) +from google.ads.googleads.v12.enums.types import location_placeholder_field +from google.ads.googleads.v12.enums.types import message_placeholder_field +from google.ads.googleads.v12.enums.types import ( + placeholder_type as gage_placeholder_type, +) +from google.ads.googleads.v12.enums.types import price_placeholder_field +from google.ads.googleads.v12.enums.types import promotion_placeholder_field +from google.ads.googleads.v12.enums.types import real_estate_placeholder_field +from google.ads.googleads.v12.enums.types import sitelink_placeholder_field +from google.ads.googleads.v12.enums.types import ( + structured_snippet_placeholder_field, +) +from google.ads.googleads.v12.enums.types import travel_placeholder_field + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"FeedMapping", "AttributeFieldMapping",}, +) + + +class FeedMapping(proto.Message): + r"""A feed mapping. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the feed mapping. Feed + mapping resource names have the form: + + ``customers/{customer_id}/feedMappings/{feed_id}~{feed_mapping_id}`` + feed (str): + Immutable. The feed of this feed mapping. + + This field is a member of `oneof`_ ``_feed``. + attribute_field_mappings (Sequence[google.ads.googleads.v12.resources.types.AttributeFieldMapping]): + Immutable. Feed attributes to field mappings. + These mappings are a one-to-many relationship + meaning that 1 feed attribute can be used to + populate multiple placeholder fields, but 1 + placeholder field can only draw data from 1 feed + attribute. Ad Customizer is an exception, 1 + placeholder field can be mapped to multiple feed + attributes. Required. + status (google.ads.googleads.v12.enums.types.FeedMappingStatusEnum.FeedMappingStatus): + Output only. Status of the feed mapping. + This field is read-only. + placeholder_type (google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType): + Immutable. The placeholder type of this + mapping (for example, if the mapping maps feed + attributes to placeholder fields). + + This field is a member of `oneof`_ ``target``. + criterion_type (google.ads.googleads.v12.enums.types.FeedMappingCriterionTypeEnum.FeedMappingCriterionType): + Immutable. The criterion type of this mapping + (for example, if the mapping maps feed + attributes to criterion fields). + + This field is a member of `oneof`_ ``target``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.STRING, number=7, optional=True,) + attribute_field_mappings = proto.RepeatedField( + proto.MESSAGE, number=5, message="AttributeFieldMapping", + ) + status = proto.Field( + proto.ENUM, + number=6, + enum=feed_mapping_status.FeedMappingStatusEnum.FeedMappingStatus, + ) + placeholder_type = proto.Field( + proto.ENUM, + number=3, + oneof="target", + enum=gage_placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + criterion_type = proto.Field( + proto.ENUM, + number=4, + oneof="target", + enum=feed_mapping_criterion_type.FeedMappingCriterionTypeEnum.FeedMappingCriterionType, + ) + + +class AttributeFieldMapping(proto.Message): + r"""Maps from feed attribute id to a placeholder or criterion + field id. + + 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: + feed_attribute_id (int): + Immutable. Feed attribute from which to map. + + This field is a member of `oneof`_ ``_feed_attribute_id``. + field_id (int): + Output only. The placeholder field ID. If a + placeholder field enum is not published in the + current API version, then this field will be + populated and the field oneof will be empty. + This field is read-only. + + This field is a member of `oneof`_ ``_field_id``. + sitelink_field (google.ads.googleads.v12.enums.types.SitelinkPlaceholderFieldEnum.SitelinkPlaceholderField): + Immutable. Sitelink Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + call_field (google.ads.googleads.v12.enums.types.CallPlaceholderFieldEnum.CallPlaceholderField): + Immutable. Call Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + app_field (google.ads.googleads.v12.enums.types.AppPlaceholderFieldEnum.AppPlaceholderField): + Immutable. App Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + location_field (google.ads.googleads.v12.enums.types.LocationPlaceholderFieldEnum.LocationPlaceholderField): + Output only. Location Placeholder Fields. + This field is read-only. + + This field is a member of `oneof`_ ``field``. + affiliate_location_field (google.ads.googleads.v12.enums.types.AffiliateLocationPlaceholderFieldEnum.AffiliateLocationPlaceholderField): + Output only. Affiliate Location Placeholder + Fields. This field is read-only. + + This field is a member of `oneof`_ ``field``. + callout_field (google.ads.googleads.v12.enums.types.CalloutPlaceholderFieldEnum.CalloutPlaceholderField): + Immutable. Callout Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + structured_snippet_field (google.ads.googleads.v12.enums.types.StructuredSnippetPlaceholderFieldEnum.StructuredSnippetPlaceholderField): + Immutable. Structured Snippet Placeholder + Fields. + + This field is a member of `oneof`_ ``field``. + message_field (google.ads.googleads.v12.enums.types.MessagePlaceholderFieldEnum.MessagePlaceholderField): + Immutable. Message Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + price_field (google.ads.googleads.v12.enums.types.PricePlaceholderFieldEnum.PricePlaceholderField): + Immutable. Price Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + promotion_field (google.ads.googleads.v12.enums.types.PromotionPlaceholderFieldEnum.PromotionPlaceholderField): + Immutable. Promotion Placeholder Fields. + + This field is a member of `oneof`_ ``field``. + ad_customizer_field (google.ads.googleads.v12.enums.types.AdCustomizerPlaceholderFieldEnum.AdCustomizerPlaceholderField): + Immutable. Ad Customizer Placeholder Fields + + This field is a member of `oneof`_ ``field``. + dsa_page_feed_field (google.ads.googleads.v12.enums.types.DsaPageFeedCriterionFieldEnum.DsaPageFeedCriterionField): + Immutable. Dynamic Search Ad Page Feed + Fields. + + This field is a member of `oneof`_ ``field``. + location_extension_targeting_field (google.ads.googleads.v12.enums.types.LocationExtensionTargetingCriterionFieldEnum.LocationExtensionTargetingCriterionField): + Immutable. Location Target Fields. + + This field is a member of `oneof`_ ``field``. + education_field (google.ads.googleads.v12.enums.types.EducationPlaceholderFieldEnum.EducationPlaceholderField): + Immutable. Education Placeholder Fields + + This field is a member of `oneof`_ ``field``. + flight_field (google.ads.googleads.v12.enums.types.FlightPlaceholderFieldEnum.FlightPlaceholderField): + Immutable. Flight Placeholder Fields + + This field is a member of `oneof`_ ``field``. + custom_field (google.ads.googleads.v12.enums.types.CustomPlaceholderFieldEnum.CustomPlaceholderField): + Immutable. Custom Placeholder Fields + + This field is a member of `oneof`_ ``field``. + hotel_field (google.ads.googleads.v12.enums.types.HotelPlaceholderFieldEnum.HotelPlaceholderField): + Immutable. Hotel Placeholder Fields + + This field is a member of `oneof`_ ``field``. + real_estate_field (google.ads.googleads.v12.enums.types.RealEstatePlaceholderFieldEnum.RealEstatePlaceholderField): + Immutable. Real Estate Placeholder Fields + + This field is a member of `oneof`_ ``field``. + travel_field (google.ads.googleads.v12.enums.types.TravelPlaceholderFieldEnum.TravelPlaceholderField): + Immutable. Travel Placeholder Fields + + This field is a member of `oneof`_ ``field``. + local_field (google.ads.googleads.v12.enums.types.LocalPlaceholderFieldEnum.LocalPlaceholderField): + Immutable. Local Placeholder Fields + + This field is a member of `oneof`_ ``field``. + job_field (google.ads.googleads.v12.enums.types.JobPlaceholderFieldEnum.JobPlaceholderField): + Immutable. Job Placeholder Fields + + This field is a member of `oneof`_ ``field``. + image_field (google.ads.googleads.v12.enums.types.ImagePlaceholderFieldEnum.ImagePlaceholderField): + Immutable. Image Placeholder Fields + + This field is a member of `oneof`_ ``field``. + """ + + feed_attribute_id = proto.Field(proto.INT64, number=24, optional=True,) + field_id = proto.Field(proto.INT64, number=25, optional=True,) + sitelink_field = proto.Field( + proto.ENUM, + number=3, + oneof="field", + enum=sitelink_placeholder_field.SitelinkPlaceholderFieldEnum.SitelinkPlaceholderField, + ) + call_field = proto.Field( + proto.ENUM, + number=4, + oneof="field", + enum=call_placeholder_field.CallPlaceholderFieldEnum.CallPlaceholderField, + ) + app_field = proto.Field( + proto.ENUM, + number=5, + oneof="field", + enum=app_placeholder_field.AppPlaceholderFieldEnum.AppPlaceholderField, + ) + location_field = proto.Field( + proto.ENUM, + number=6, + oneof="field", + enum=location_placeholder_field.LocationPlaceholderFieldEnum.LocationPlaceholderField, + ) + affiliate_location_field = proto.Field( + proto.ENUM, + number=7, + oneof="field", + enum=affiliate_location_placeholder_field.AffiliateLocationPlaceholderFieldEnum.AffiliateLocationPlaceholderField, + ) + callout_field = proto.Field( + proto.ENUM, + number=8, + oneof="field", + enum=callout_placeholder_field.CalloutPlaceholderFieldEnum.CalloutPlaceholderField, + ) + structured_snippet_field = proto.Field( + proto.ENUM, + number=9, + oneof="field", + enum=structured_snippet_placeholder_field.StructuredSnippetPlaceholderFieldEnum.StructuredSnippetPlaceholderField, + ) + message_field = proto.Field( + proto.ENUM, + number=10, + oneof="field", + enum=message_placeholder_field.MessagePlaceholderFieldEnum.MessagePlaceholderField, + ) + price_field = proto.Field( + proto.ENUM, + number=11, + oneof="field", + enum=price_placeholder_field.PricePlaceholderFieldEnum.PricePlaceholderField, + ) + promotion_field = proto.Field( + proto.ENUM, + number=12, + oneof="field", + enum=promotion_placeholder_field.PromotionPlaceholderFieldEnum.PromotionPlaceholderField, + ) + ad_customizer_field = proto.Field( + proto.ENUM, + number=13, + oneof="field", + enum=ad_customizer_placeholder_field.AdCustomizerPlaceholderFieldEnum.AdCustomizerPlaceholderField, + ) + dsa_page_feed_field = proto.Field( + proto.ENUM, + number=14, + oneof="field", + enum=dsa_page_feed_criterion_field.DsaPageFeedCriterionFieldEnum.DsaPageFeedCriterionField, + ) + location_extension_targeting_field = proto.Field( + proto.ENUM, + number=15, + oneof="field", + enum=location_extension_targeting_criterion_field.LocationExtensionTargetingCriterionFieldEnum.LocationExtensionTargetingCriterionField, + ) + education_field = proto.Field( + proto.ENUM, + number=16, + oneof="field", + enum=education_placeholder_field.EducationPlaceholderFieldEnum.EducationPlaceholderField, + ) + flight_field = proto.Field( + proto.ENUM, + number=17, + oneof="field", + enum=flight_placeholder_field.FlightPlaceholderFieldEnum.FlightPlaceholderField, + ) + custom_field = proto.Field( + proto.ENUM, + number=18, + oneof="field", + enum=custom_placeholder_field.CustomPlaceholderFieldEnum.CustomPlaceholderField, + ) + hotel_field = proto.Field( + proto.ENUM, + number=19, + oneof="field", + enum=hotel_placeholder_field.HotelPlaceholderFieldEnum.HotelPlaceholderField, + ) + real_estate_field = proto.Field( + proto.ENUM, + number=20, + oneof="field", + enum=real_estate_placeholder_field.RealEstatePlaceholderFieldEnum.RealEstatePlaceholderField, + ) + travel_field = proto.Field( + proto.ENUM, + number=21, + oneof="field", + enum=travel_placeholder_field.TravelPlaceholderFieldEnum.TravelPlaceholderField, + ) + local_field = proto.Field( + proto.ENUM, + number=22, + oneof="field", + enum=local_placeholder_field.LocalPlaceholderFieldEnum.LocalPlaceholderField, + ) + job_field = proto.Field( + proto.ENUM, + number=23, + oneof="field", + enum=job_placeholder_field.JobPlaceholderFieldEnum.JobPlaceholderField, + ) + image_field = proto.Field( + proto.ENUM, + number=26, + oneof="field", + enum=image_placeholder_field.ImagePlaceholderFieldEnum.ImagePlaceholderField, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/feed_placeholder_view.py b/google/ads/googleads/v12/resources/types/feed_placeholder_view.py new file mode 100644 index 000000000..22efabfe7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/feed_placeholder_view.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + placeholder_type as gage_placeholder_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"FeedPlaceholderView",}, +) + + +class FeedPlaceholderView(proto.Message): + r"""A feed placeholder view. + + Attributes: + resource_name (str): + Output only. The resource name of the feed placeholder view. + Feed placeholder view resource names have the form: + + ``customers/{customer_id}/feedPlaceholderViews/{placeholder_type}`` + placeholder_type (google.ads.googleads.v12.enums.types.PlaceholderTypeEnum.PlaceholderType): + Output only. The placeholder type of the feed + placeholder view. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + placeholder_type = proto.Field( + proto.ENUM, + number=2, + enum=gage_placeholder_type.PlaceholderTypeEnum.PlaceholderType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/gender_view.py b/google/ads/googleads/v12/resources/types/gender_view.py new file mode 100644 index 000000000..3decddfd7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/gender_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"GenderView",}, +) + + +class GenderView(proto.Message): + r"""A gender view. + + Attributes: + resource_name (str): + Output only. The resource name of the gender view. Gender + view resource names have the form: + + ``customers/{customer_id}/genderViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/geo_target_constant.py b/google/ads/googleads/v12/resources/types/geo_target_constant.py new file mode 100644 index 000000000..7d87906da --- /dev/null +++ b/google/ads/googleads/v12/resources/types/geo_target_constant.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import geo_target_constant_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"GeoTargetConstant",}, +) + + +class GeoTargetConstant(proto.Message): + r"""A geo target constant. + + Attributes: + resource_name (str): + Output only. The resource name of the geo target constant. + Geo target constant resource names have the form: + + ``geoTargetConstants/{geo_target_constant_id}`` + id (int): + Output only. The ID of the geo target + constant. + + This field is a member of `oneof`_ ``_id``. + name (str): + Output only. Geo target constant English + name. + + This field is a member of `oneof`_ ``_name``. + country_code (str): + Output only. The ISO-3166-1 alpha-2 country + code that is associated with the target. + + This field is a member of `oneof`_ ``_country_code``. + target_type (str): + Output only. Geo target constant target type. + + This field is a member of `oneof`_ ``_target_type``. + status (google.ads.googleads.v12.enums.types.GeoTargetConstantStatusEnum.GeoTargetConstantStatus): + Output only. Geo target constant status. + canonical_name (str): + Output only. The fully qualified English + name, consisting of the target's name and that + of its parent and country. + + This field is a member of `oneof`_ ``_canonical_name``. + parent_geo_target (str): + Output only. The resource name of the parent geo target + constant. Geo target constant resource names have the form: + + ``geoTargetConstants/{parent_geo_target_constant_id}`` + + This field is a member of `oneof`_ ``_parent_geo_target``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=10, optional=True,) + name = proto.Field(proto.STRING, number=11, optional=True,) + country_code = proto.Field(proto.STRING, number=12, optional=True,) + target_type = proto.Field(proto.STRING, number=13, optional=True,) + status = proto.Field( + proto.ENUM, + number=7, + enum=geo_target_constant_status.GeoTargetConstantStatusEnum.GeoTargetConstantStatus, + ) + canonical_name = proto.Field(proto.STRING, number=14, optional=True,) + parent_geo_target = proto.Field(proto.STRING, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/geographic_view.py b/google/ads/googleads/v12/resources/types/geographic_view.py new file mode 100644 index 000000000..b9946f4a3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/geographic_view.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import geo_targeting_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"GeographicView",}, +) + + +class GeographicView(proto.Message): + r"""A geographic view. + Geographic View includes all metrics aggregated at the country + level, one row per country. It reports metrics at either actual + physical location of the user or an area of interest. If other + segment fields are used, you may get more than one row per + country. + + Attributes: + resource_name (str): + Output only. The resource name of the geographic view. + Geographic view resource names have the form: + + ``customers/{customer_id}/geographicViews/{country_criterion_id}~{location_type}`` + location_type (google.ads.googleads.v12.enums.types.GeoTargetingTypeEnum.GeoTargetingType): + Output only. Type of the geo targeting of the + campaign. + country_criterion_id (int): + Output only. Criterion Id for the country. + + This field is a member of `oneof`_ ``_country_criterion_id``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + location_type = proto.Field( + proto.ENUM, + number=3, + enum=geo_targeting_type.GeoTargetingTypeEnum.GeoTargetingType, + ) + country_criterion_id = proto.Field(proto.INT64, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/google_ads_field.py b/google/ads/googleads/v12/resources/types/google_ads_field.py new file mode 100644 index 000000000..d42eac62b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/google_ads_field.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import google_ads_field_category +from google.ads.googleads.v12.enums.types import google_ads_field_data_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"GoogleAdsField",}, +) + + +class GoogleAdsField(proto.Message): + r"""A field or resource (artifact) used by GoogleAdsService. + + Attributes: + resource_name (str): + Output only. The resource name of the artifact. Artifact + resource names have the form: + + ``googleAdsFields/{name}`` + name (str): + Output only. The name of the artifact. + + This field is a member of `oneof`_ ``_name``. + category (google.ads.googleads.v12.enums.types.GoogleAdsFieldCategoryEnum.GoogleAdsFieldCategory): + Output only. The category of the artifact. + selectable (bool): + Output only. Whether the artifact can be used + in a SELECT clause in search queries. + + This field is a member of `oneof`_ ``_selectable``. + filterable (bool): + Output only. Whether the artifact can be used + in a WHERE clause in search queries. + + This field is a member of `oneof`_ ``_filterable``. + sortable (bool): + Output only. Whether the artifact can be used + in a ORDER BY clause in search queries. + + This field is a member of `oneof`_ ``_sortable``. + selectable_with (Sequence[str]): + Output only. The names of all resources, + segments, and metrics that are selectable with + the described artifact. + attribute_resources (Sequence[str]): + Output only. The names of all resources that + are selectable with the described artifact. + Fields from these resources do not segment + metrics when included in search queries. + + This field is only set for artifacts whose + category is RESOURCE. + metrics (Sequence[str]): + Output only. This field lists the names of + all metrics that are selectable with the + described artifact when it is used in the FROM + clause. It is only set for artifacts whose + category is RESOURCE. + segments (Sequence[str]): + Output only. This field lists the names of + all artifacts, whether a segment or another + resource, that segment metrics when included in + search queries and when the described artifact + is used in the FROM clause. It is only set for + artifacts whose category is RESOURCE. + enum_values (Sequence[str]): + Output only. Values the artifact can assume + if it is a field of type ENUM. + This field is only set for artifacts of category + SEGMENT or ATTRIBUTE. + data_type (google.ads.googleads.v12.enums.types.GoogleAdsFieldDataTypeEnum.GoogleAdsFieldDataType): + Output only. This field determines the + operators that can be used with the artifact in + WHERE clauses. + type_url (str): + Output only. The URL of proto describing the + artifact's data type. + + This field is a member of `oneof`_ ``_type_url``. + is_repeated (bool): + Output only. Whether the field artifact is + repeated. + + This field is a member of `oneof`_ ``_is_repeated``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + name = proto.Field(proto.STRING, number=21, optional=True,) + category = proto.Field( + proto.ENUM, + number=3, + enum=google_ads_field_category.GoogleAdsFieldCategoryEnum.GoogleAdsFieldCategory, + ) + selectable = proto.Field(proto.BOOL, number=22, optional=True,) + filterable = proto.Field(proto.BOOL, number=23, optional=True,) + sortable = proto.Field(proto.BOOL, number=24, optional=True,) + selectable_with = proto.RepeatedField(proto.STRING, number=25,) + attribute_resources = proto.RepeatedField(proto.STRING, number=26,) + metrics = proto.RepeatedField(proto.STRING, number=27,) + segments = proto.RepeatedField(proto.STRING, number=28,) + enum_values = proto.RepeatedField(proto.STRING, number=29,) + data_type = proto.Field( + proto.ENUM, + number=12, + enum=google_ads_field_data_type.GoogleAdsFieldDataTypeEnum.GoogleAdsFieldDataType, + ) + type_url = proto.Field(proto.STRING, number=30, optional=True,) + is_repeated = proto.Field(proto.BOOL, number=31, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/group_placement_view.py b/google/ads/googleads/v12/resources/types/group_placement_view.py new file mode 100644 index 000000000..6db987ca8 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/group_placement_view.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + placement_type as gage_placement_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"GroupPlacementView",}, +) + + +class GroupPlacementView(proto.Message): + r"""A group placement view. + + Attributes: + resource_name (str): + Output only. The resource name of the group placement view. + Group placement view resource names have the form: + + ``customers/{customer_id}/groupPlacementViews/{ad_group_id}~{base64_placement}`` + placement (str): + Output only. The automatic placement string + at group level, e. g. web domain, mobile app ID, + or a YouTube channel ID. + + This field is a member of `oneof`_ ``_placement``. + display_name (str): + Output only. Domain name for websites and + YouTube channel name for YouTube channels. + + This field is a member of `oneof`_ ``_display_name``. + target_url (str): + Output only. URL of the group placement, for + example, domain, link to the mobile application + in app store, or a YouTube channel URL. + + This field is a member of `oneof`_ ``_target_url``. + placement_type (google.ads.googleads.v12.enums.types.PlacementTypeEnum.PlacementType): + Output only. Type of the placement, for + example, Website, YouTube Channel, Mobile + Application. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + placement = proto.Field(proto.STRING, number=6, optional=True,) + display_name = proto.Field(proto.STRING, number=7, optional=True,) + target_url = proto.Field(proto.STRING, number=8, optional=True,) + placement_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_placement_type.PlacementTypeEnum.PlacementType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/hotel_group_view.py b/google/ads/googleads/v12/resources/types/hotel_group_view.py new file mode 100644 index 000000000..66d06b515 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/hotel_group_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"HotelGroupView",}, +) + + +class HotelGroupView(proto.Message): + r"""A hotel group view. + + Attributes: + resource_name (str): + Output only. The resource name of the hotel group view. + Hotel Group view resource names have the form: + + ``customers/{customer_id}/hotelGroupViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/hotel_performance_view.py b/google/ads/googleads/v12/resources/types/hotel_performance_view.py new file mode 100644 index 000000000..d2a1a2a84 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/hotel_performance_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"HotelPerformanceView",}, +) + + +class HotelPerformanceView(proto.Message): + r"""A hotel performance view. + + Attributes: + resource_name (str): + Output only. The resource name of the hotel performance + view. Hotel performance view resource names have the form: + + ``customers/{customer_id}/hotelPerformanceView`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/hotel_reconciliation.py b/google/ads/googleads/v12/resources/types/hotel_reconciliation.py new file mode 100644 index 000000000..3ea517780 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/hotel_reconciliation.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import hotel_reconciliation_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"HotelReconciliation",}, +) + + +class HotelReconciliation(proto.Message): + r"""A hotel reconciliation. It contains conversion information + from Hotel bookings to reconcile with advertiser records. These + rows may be updated or canceled before billing through Bulk + Uploads. + + Attributes: + resource_name (str): + Immutable. The resource name of the hotel reconciliation. + Hotel reconciliation resource names have the form: + + ``customers/{customer_id}/hotelReconciliations/{commission_id}`` + commission_id (str): + Required. Output only. The commission ID is + Google's ID for this booking. Every booking + event is assigned a Commission ID to help you + match it to a guest stay. + order_id (str): + Output only. The order ID is the identifier for this booking + as provided in the 'transaction_id' parameter of the + conversion tracking tag. + campaign (str): + Output only. The resource name for the + Campaign associated with the conversion. + hotel_center_id (int): + Output only. Identifier for the Hotel Center + account which provides the rates for the Hotel + campaign. + hotel_id (str): + Output only. Unique identifier for the booked + property, as provided in the Hotel Center feed. + The hotel ID comes from the 'ID' parameter of + the conversion tracking tag. + check_in_date (str): + Output only. Check-in date recorded when the + booking is made. If the check-in date is + modified at reconciliation, the revised date + will then take the place of the original date in + this column. Format is YYYY-MM-DD. + check_out_date (str): + Output only. Check-out date recorded when the + booking is made. If the check-in date is + modified at reconciliation, the revised date + will then take the place of the original date in + this column. Format is YYYY-MM-DD. + reconciled_value_micros (int): + Required. Output only. Reconciled value is + the final value of a booking as paid by the + guest. If original booking value changes for any + reason, such as itinerary changes or room + upsells, the reconciled value should be the full + final amount collected. If a booking is + canceled, the reconciled value should include + the value of any cancellation fees or + non-refundable nights charged. Value is in + millionths of the base unit currency. For + example, $12.35 would be represented as + 12350000. Currency unit is in the default + customer currency. + billed (bool): + Output only. Whether a given booking has been + billed. Once billed, a booking can't be + modified. + status (google.ads.googleads.v12.enums.types.HotelReconciliationStatusEnum.HotelReconciliationStatus): + Required. Output only. Current status of a + booking with regards to reconciliation and + billing. Bookings should be reconciled within 45 + days after the check-out date. Any booking not + reconciled within 45 days will be billed at its + original value. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + commission_id = proto.Field(proto.STRING, number=2,) + order_id = proto.Field(proto.STRING, number=3,) + campaign = proto.Field(proto.STRING, number=11,) + hotel_center_id = proto.Field(proto.INT64, number=4,) + hotel_id = proto.Field(proto.STRING, number=5,) + check_in_date = proto.Field(proto.STRING, number=6,) + check_out_date = proto.Field(proto.STRING, number=7,) + reconciled_value_micros = proto.Field(proto.INT64, number=8,) + billed = proto.Field(proto.BOOL, number=9,) + status = proto.Field( + proto.ENUM, + number=10, + enum=hotel_reconciliation_status.HotelReconciliationStatusEnum.HotelReconciliationStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/income_range_view.py b/google/ads/googleads/v12/resources/types/income_range_view.py new file mode 100644 index 000000000..3d036ebb9 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/income_range_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"IncomeRangeView",}, +) + + +class IncomeRangeView(proto.Message): + r"""An income range view. + + Attributes: + resource_name (str): + Output only. The resource name of the income range view. + Income range view resource names have the form: + + ``customers/{customer_id}/incomeRangeViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/invoice.py b/google/ads/googleads/v12/resources/types/invoice.py new file mode 100644 index 000000000..2c6ce770b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/invoice.py @@ -0,0 +1,473 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import dates +from google.ads.googleads.v12.enums.types import invoice_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Invoice",}, +) + + +class Invoice(proto.Message): + r"""An invoice. All invoice information is snapshotted to match + the PDF invoice. For invoices older than the launch of + InvoiceService, the snapshotted information may not match the + PDF invoice. + + Attributes: + resource_name (str): + Output only. The resource name of the invoice. Multiple + customers can share a given invoice, so multiple resource + names may point to the same invoice. Invoice resource names + have the form: + + ``customers/{customer_id}/invoices/{invoice_id}`` + id (str): + Output only. The ID of the invoice. It + appears on the invoice PDF as "Invoice number". + + This field is a member of `oneof`_ ``_id``. + type_ (google.ads.googleads.v12.enums.types.InvoiceTypeEnum.InvoiceType): + Output only. The type of invoice. + billing_setup (str): + Output only. The resource name of this invoice's billing + setup. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + + This field is a member of `oneof`_ ``_billing_setup``. + payments_account_id (str): + Output only. A 16 digit ID used to identify + the payments account associated with the billing + setup, for example, "1234-5678-9012-3456". It + appears on the invoice PDF as "Billing Account + Number". + + This field is a member of `oneof`_ ``_payments_account_id``. + payments_profile_id (str): + Output only. A 12 digit ID used to identify + the payments profile associated with the billing + setup, for example, "1234-5678-9012". It appears + on the invoice PDF as "Billing ID". + + This field is a member of `oneof`_ ``_payments_profile_id``. + issue_date (str): + Output only. The issue date in yyyy-mm-dd + format. It appears on the invoice PDF as either + "Issue date" or "Invoice date". + + This field is a member of `oneof`_ ``_issue_date``. + due_date (str): + Output only. The due date in yyyy-mm-dd + format. + + This field is a member of `oneof`_ ``_due_date``. + service_date_range (google.ads.googleads.v12.common.types.DateRange): + Output only. The service period date range of + this invoice. The end date is inclusive. + currency_code (str): + Output only. The currency code. All costs are + returned in this currency. A subset of the + currency codes derived from the ISO 4217 + standard is supported. + + This field is a member of `oneof`_ ``_currency_code``. + adjustments_subtotal_amount_micros (int): + Output only. The pretax subtotal amount of + invoice level adjustments, in micros. + adjustments_tax_amount_micros (int): + Output only. The sum of taxes on the invoice + level adjustments, in micros. + adjustments_total_amount_micros (int): + Output only. The total amount of invoice + level adjustments, in micros. + regulatory_costs_subtotal_amount_micros (int): + Output only. The pretax subtotal amount of + invoice level regulatory costs, in micros. + regulatory_costs_tax_amount_micros (int): + Output only. The sum of taxes on the invoice + level regulatory costs, in micros. + regulatory_costs_total_amount_micros (int): + Output only. The total amount of invoice + level regulatory costs, in micros. + subtotal_amount_micros (int): + Output only. The pretax subtotal amount, in micros. This + equals the sum of the AccountBudgetSummary subtotal amounts, + Invoice.adjustments_subtotal_amount_micros, and + Invoice.regulatory_costs_subtotal_amount_micros. Starting + with v6, the Invoice.regulatory_costs_subtotal_amount_micros + is no longer included. + + This field is a member of `oneof`_ ``_subtotal_amount_micros``. + tax_amount_micros (int): + Output only. The sum of all taxes on the + invoice, in micros. This equals the sum of the + AccountBudgetSummary tax amounts, plus taxes not + associated with a specific account budget. + + This field is a member of `oneof`_ ``_tax_amount_micros``. + total_amount_micros (int): + Output only. The total amount, in micros. This equals the + sum of Invoice.subtotal_amount_micros and + Invoice.tax_amount_micros. Starting with v6, + Invoice.regulatory_costs_subtotal_amount_micros is also + added as it is no longer already included in + Invoice.tax_amount_micros. + + This field is a member of `oneof`_ ``_total_amount_micros``. + corrected_invoice (str): + Output only. The resource name of the original invoice + corrected, wrote off, or canceled by this invoice, if + applicable. If ``corrected_invoice`` is set, + ``replaced_invoices`` will not be set. Invoice resource + names have the form: + + ``customers/{customer_id}/invoices/{invoice_id}`` + + This field is a member of `oneof`_ ``_corrected_invoice``. + replaced_invoices (Sequence[str]): + Output only. The resource name of the original invoice(s) + being rebilled or replaced by this invoice, if applicable. + There might be multiple replaced invoices due to invoice + consolidation. The replaced invoices may not belong to the + same payments account. If ``replaced_invoices`` is set, + ``corrected_invoice`` will not be set. Invoice resource + names have the form: + + ``customers/{customer_id}/invoices/{invoice_id}`` + pdf_url (str): + Output only. The URL to a PDF copy of the + invoice. Users need to pass in their OAuth token + to request the PDF with this URL. + + This field is a member of `oneof`_ ``_pdf_url``. + account_budget_summaries (Sequence[google.ads.googleads.v12.resources.types.Invoice.AccountBudgetSummary]): + Output only. The list of summarized account + budget information associated with this invoice. + account_summaries (Sequence[google.ads.googleads.v12.resources.types.Invoice.AccountSummary]): + Output only. The list of summarized account + information associated with this invoice. + """ + + class AccountSummary(proto.Message): + r"""Represents a summarized view at account level. + AccountSummary fields are accessible only to customers on the + allow-list. + + Attributes: + customer (str): + Output only. The account associated with the + account summary. + + This field is a member of `oneof`_ ``_customer``. + billing_correction_subtotal_amount_micros (int): + Output only. Pretax billing correction + subtotal amount, in micros. + + This field is a member of `oneof`_ ``_billing_correction_subtotal_amount_micros``. + billing_correction_tax_amount_micros (int): + Output only. Tax on billing correction, in + micros. + + This field is a member of `oneof`_ ``_billing_correction_tax_amount_micros``. + billing_correction_total_amount_micros (int): + Output only. Total billing correction amount, + in micros. + + This field is a member of `oneof`_ ``_billing_correction_total_amount_micros``. + coupon_adjustment_subtotal_amount_micros (int): + Output only. Pretax coupon adjustment + subtotal amount, in micros. + + This field is a member of `oneof`_ ``_coupon_adjustment_subtotal_amount_micros``. + coupon_adjustment_tax_amount_micros (int): + Output only. Tax on coupon adjustment, in + micros. + + This field is a member of `oneof`_ ``_coupon_adjustment_tax_amount_micros``. + coupon_adjustment_total_amount_micros (int): + Output only. Total coupon adjustment amount, + in micros. + + This field is a member of `oneof`_ ``_coupon_adjustment_total_amount_micros``. + excess_credit_adjustment_subtotal_amount_micros (int): + Output only. Pretax excess credit adjustment + subtotal amount, in micros. + + This field is a member of `oneof`_ ``_excess_credit_adjustment_subtotal_amount_micros``. + excess_credit_adjustment_tax_amount_micros (int): + Output only. Tax on excess credit adjustment, + in micros. + + This field is a member of `oneof`_ ``_excess_credit_adjustment_tax_amount_micros``. + excess_credit_adjustment_total_amount_micros (int): + Output only. Total excess credit adjustment + amount, in micros. + + This field is a member of `oneof`_ ``_excess_credit_adjustment_total_amount_micros``. + regulatory_costs_subtotal_amount_micros (int): + Output only. Pretax regulatory costs subtotal + amount, in micros. + + This field is a member of `oneof`_ ``_regulatory_costs_subtotal_amount_micros``. + regulatory_costs_tax_amount_micros (int): + Output only. Tax on regulatory costs, in + micros. + + This field is a member of `oneof`_ ``_regulatory_costs_tax_amount_micros``. + regulatory_costs_total_amount_micros (int): + Output only. Total regulatory costs amount, + in micros. + + This field is a member of `oneof`_ ``_regulatory_costs_total_amount_micros``. + subtotal_amount_micros (int): + Output only. Total pretax subtotal amount + attributable to the account during the service + period, in micros. + + This field is a member of `oneof`_ ``_subtotal_amount_micros``. + tax_amount_micros (int): + Output only. Total tax amount attributable to + the account during the service period, in + micros. + + This field is a member of `oneof`_ ``_tax_amount_micros``. + total_amount_micros (int): + Output only. Total amount attributable to the account during + the service period, in micros. This equals the sum of the + subtotal_amount_micros and tax_amount_micros. + + This field is a member of `oneof`_ ``_total_amount_micros``. + """ + + customer = proto.Field(proto.STRING, number=1, optional=True,) + billing_correction_subtotal_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + billing_correction_tax_amount_micros = proto.Field( + proto.INT64, number=3, optional=True, + ) + billing_correction_total_amount_micros = proto.Field( + proto.INT64, number=4, optional=True, + ) + coupon_adjustment_subtotal_amount_micros = proto.Field( + proto.INT64, number=5, optional=True, + ) + coupon_adjustment_tax_amount_micros = proto.Field( + proto.INT64, number=6, optional=True, + ) + coupon_adjustment_total_amount_micros = proto.Field( + proto.INT64, number=7, optional=True, + ) + excess_credit_adjustment_subtotal_amount_micros = proto.Field( + proto.INT64, number=8, optional=True, + ) + excess_credit_adjustment_tax_amount_micros = proto.Field( + proto.INT64, number=9, optional=True, + ) + excess_credit_adjustment_total_amount_micros = proto.Field( + proto.INT64, number=10, optional=True, + ) + regulatory_costs_subtotal_amount_micros = proto.Field( + proto.INT64, number=11, optional=True, + ) + regulatory_costs_tax_amount_micros = proto.Field( + proto.INT64, number=12, optional=True, + ) + regulatory_costs_total_amount_micros = proto.Field( + proto.INT64, number=13, optional=True, + ) + subtotal_amount_micros = proto.Field( + proto.INT64, number=14, optional=True, + ) + tax_amount_micros = proto.Field(proto.INT64, number=15, optional=True,) + total_amount_micros = proto.Field( + proto.INT64, number=16, optional=True, + ) + + class AccountBudgetSummary(proto.Message): + r"""Represents a summarized account budget billable cost. + + Attributes: + customer (str): + Output only. The resource name of the customer associated + with this account budget. This contains the customer ID, + which appears on the invoice PDF as "Account ID". Customer + resource names have the form: + + ``customers/{customer_id}`` + + This field is a member of `oneof`_ ``_customer``. + customer_descriptive_name (str): + Output only. The descriptive name of the + account budget's customer. It appears on the + invoice PDF as "Account". + + This field is a member of `oneof`_ ``_customer_descriptive_name``. + account_budget (str): + Output only. The resource name of the account budget + associated with this summarized billable cost. AccountBudget + resource names have the form: + + ``customers/{customer_id}/accountBudgets/{account_budget_id}`` + + This field is a member of `oneof`_ ``_account_budget``. + account_budget_name (str): + Output only. The name of the account budget. + It appears on the invoice PDF as "Account + budget". + + This field is a member of `oneof`_ ``_account_budget_name``. + purchase_order_number (str): + Output only. The purchase order number of the + account budget. It appears on the invoice PDF as + "Purchase order". + + This field is a member of `oneof`_ ``_purchase_order_number``. + subtotal_amount_micros (int): + Output only. The pretax subtotal amount + attributable to this budget during the service + period, in micros. + + This field is a member of `oneof`_ ``_subtotal_amount_micros``. + tax_amount_micros (int): + Output only. The tax amount attributable to + this budget during the service period, in + micros. + + This field is a member of `oneof`_ ``_tax_amount_micros``. + total_amount_micros (int): + Output only. The total amount attributable to + this budget during the service period, in + micros. This equals the sum of the account + budget subtotal amount and the account budget + tax amount. + + This field is a member of `oneof`_ ``_total_amount_micros``. + billable_activity_date_range (google.ads.googleads.v12.common.types.DateRange): + Output only. The billable activity date range + of the account budget, within the service date + range of this invoice. The end date is + inclusive. This can be different from the + account budget's start and end time. + served_amount_micros (int): + Output only. Accessible only to customers on + the allow-list. The pretax served amount + attributable to this budget during the service + period, in micros. This is only useful to + reconcile invoice and delivery data. + + This field is a member of `oneof`_ ``_served_amount_micros``. + billed_amount_micros (int): + Output only. Accessible only to customers on + the allow-list. The pretax billed amount + attributable to this budget during the service + period, in micros. This does not account for any + adjustments. + + This field is a member of `oneof`_ ``_billed_amount_micros``. + overdelivery_amount_micros (int): + Output only. Accessible only to customers on + the allow-list. The pretax overdelivery amount + attributable to this budget during the service + period, in micros (negative value). + + This field is a member of `oneof`_ ``_overdelivery_amount_micros``. + invalid_activity_amount_micros (int): + Output only. Accessible only to customers on + the allow-list. The pretax invalid activity + amount attributable to this budget in previous + months, in micros (negative value). + + This field is a member of `oneof`_ ``_invalid_activity_amount_micros``. + """ + + customer = proto.Field(proto.STRING, number=10, optional=True,) + customer_descriptive_name = proto.Field( + proto.STRING, number=11, optional=True, + ) + account_budget = proto.Field(proto.STRING, number=12, optional=True,) + account_budget_name = proto.Field( + proto.STRING, number=13, optional=True, + ) + purchase_order_number = proto.Field( + proto.STRING, number=14, optional=True, + ) + subtotal_amount_micros = proto.Field( + proto.INT64, number=15, optional=True, + ) + tax_amount_micros = proto.Field(proto.INT64, number=16, optional=True,) + total_amount_micros = proto.Field( + proto.INT64, number=17, optional=True, + ) + billable_activity_date_range = proto.Field( + proto.MESSAGE, number=9, message=dates.DateRange, + ) + served_amount_micros = proto.Field( + proto.INT64, number=18, optional=True, + ) + billed_amount_micros = proto.Field( + proto.INT64, number=19, optional=True, + ) + overdelivery_amount_micros = proto.Field( + proto.INT64, number=20, optional=True, + ) + invalid_activity_amount_micros = proto.Field( + proto.INT64, number=21, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.STRING, number=25, optional=True,) + type_ = proto.Field( + proto.ENUM, number=3, enum=invoice_type.InvoiceTypeEnum.InvoiceType, + ) + billing_setup = proto.Field(proto.STRING, number=26, optional=True,) + payments_account_id = proto.Field(proto.STRING, number=27, optional=True,) + payments_profile_id = proto.Field(proto.STRING, number=28, optional=True,) + issue_date = proto.Field(proto.STRING, number=29, optional=True,) + due_date = proto.Field(proto.STRING, number=30, optional=True,) + service_date_range = proto.Field( + proto.MESSAGE, number=9, message=dates.DateRange, + ) + currency_code = proto.Field(proto.STRING, number=31, optional=True,) + adjustments_subtotal_amount_micros = proto.Field(proto.INT64, number=19,) + adjustments_tax_amount_micros = proto.Field(proto.INT64, number=20,) + adjustments_total_amount_micros = proto.Field(proto.INT64, number=21,) + regulatory_costs_subtotal_amount_micros = proto.Field( + proto.INT64, number=22, + ) + regulatory_costs_tax_amount_micros = proto.Field(proto.INT64, number=23,) + regulatory_costs_total_amount_micros = proto.Field(proto.INT64, number=24,) + subtotal_amount_micros = proto.Field(proto.INT64, number=33, optional=True,) + tax_amount_micros = proto.Field(proto.INT64, number=34, optional=True,) + total_amount_micros = proto.Field(proto.INT64, number=35, optional=True,) + corrected_invoice = proto.Field(proto.STRING, number=36, optional=True,) + replaced_invoices = proto.RepeatedField(proto.STRING, number=37,) + pdf_url = proto.Field(proto.STRING, number=38, optional=True,) + account_budget_summaries = proto.RepeatedField( + proto.MESSAGE, number=18, message=AccountBudgetSummary, + ) + account_summaries = proto.RepeatedField( + proto.MESSAGE, number=39, message=AccountSummary, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_plan.py b/google/ads/googleads/v12/resources/types/keyword_plan.py new file mode 100644 index 000000000..e3055dbf1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_plan.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import dates +from google.ads.googleads.v12.enums.types import keyword_plan_forecast_interval + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlan", "KeywordPlanForecastPeriod",}, +) + + +class KeywordPlan(proto.Message): + r"""A Keyword Planner plan. + Max number of saved keyword plans: 10000. + It's possible to remove plans if limit is reached. + + Attributes: + resource_name (str): + Immutable. The resource name of the Keyword Planner plan. + KeywordPlan resource names have the form: + + ``customers/{customer_id}/keywordPlans/{kp_plan_id}`` + id (int): + Output only. The ID of the keyword plan. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the keyword plan. + This field is required and should not be empty + when creating new keyword plans. + + This field is a member of `oneof`_ ``_name``. + forecast_period (google.ads.googleads.v12.resources.types.KeywordPlanForecastPeriod): + The date period used for forecasting the + plan. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=5, optional=True,) + name = proto.Field(proto.STRING, number=6, optional=True,) + forecast_period = proto.Field( + proto.MESSAGE, number=4, message="KeywordPlanForecastPeriod", + ) + + +class KeywordPlanForecastPeriod(proto.Message): + r"""The forecasting period associated with the keyword plan. + + 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: + date_interval (google.ads.googleads.v12.enums.types.KeywordPlanForecastIntervalEnum.KeywordPlanForecastInterval): + A future date range relative to the current + date used for forecasting. + + This field is a member of `oneof`_ ``interval``. + date_range (google.ads.googleads.v12.common.types.DateRange): + The custom date range used for forecasting. + It cannot be greater than a year. + The start and end dates must be in the future. + Otherwise, an error will be returned when the + forecasting action is performed. The start and + end dates are inclusive. + + This field is a member of `oneof`_ ``interval``. + """ + + date_interval = proto.Field( + proto.ENUM, + number=1, + oneof="interval", + enum=keyword_plan_forecast_interval.KeywordPlanForecastIntervalEnum.KeywordPlanForecastInterval, + ) + date_range = proto.Field( + proto.MESSAGE, number=2, oneof="interval", message=dates.DateRange, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_plan_ad_group.py b/google/ads/googleads/v12/resources/types/keyword_plan_ad_group.py new file mode 100644 index 000000000..28d78c9c1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_plan_ad_group.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanAdGroup",}, +) + + +class KeywordPlanAdGroup(proto.Message): + r"""A Keyword Planner ad group. + Max number of keyword plan ad groups per plan: 200. + + Attributes: + resource_name (str): + Immutable. The resource name of the Keyword Planner ad + group. KeywordPlanAdGroup resource names have the form: + + ``customers/{customer_id}/keywordPlanAdGroups/{kp_ad_group_id}`` + keyword_plan_campaign (str): + The keyword plan campaign to which this ad + group belongs. + + This field is a member of `oneof`_ ``_keyword_plan_campaign``. + id (int): + Output only. The ID of the keyword plan ad + group. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the keyword plan ad group. + This field is required and should not be empty + when creating keyword plan ad group. + + This field is a member of `oneof`_ ``_name``. + cpc_bid_micros (int): + A default ad group max cpc bid in micros in + account currency for all biddable keywords under + the keyword plan ad group. If not set, will + inherit from parent campaign. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + keyword_plan_campaign = proto.Field(proto.STRING, number=6, optional=True,) + id = proto.Field(proto.INT64, number=7, optional=True,) + name = proto.Field(proto.STRING, number=8, optional=True,) + cpc_bid_micros = proto.Field(proto.INT64, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_plan_ad_group_keyword.py b/google/ads/googleads/v12/resources/types/keyword_plan_ad_group_keyword.py new file mode 100644 index 000000000..0a4a3e200 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_plan_ad_group_keyword.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import keyword_match_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanAdGroupKeyword",}, +) + + +class KeywordPlanAdGroupKeyword(proto.Message): + r"""A Keyword Plan ad group keyword. + Max number of keyword plan keywords per plan: 10000. + + Attributes: + resource_name (str): + Immutable. The resource name of the Keyword Plan ad group + keyword. KeywordPlanAdGroupKeyword resource names have the + form: + + ``customers/{customer_id}/keywordPlanAdGroupKeywords/{kp_ad_group_keyword_id}`` + keyword_plan_ad_group (str): + The Keyword Plan ad group to which this + keyword belongs. + + This field is a member of `oneof`_ ``_keyword_plan_ad_group``. + id (int): + Output only. The ID of the Keyword Plan + keyword. + + This field is a member of `oneof`_ ``_id``. + text (str): + The keyword text. + + This field is a member of `oneof`_ ``_text``. + match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + The keyword match type. + cpc_bid_micros (int): + A keyword level max cpc bid in micros (for + example, $1 = 1mm). The currency is the same as + the account currency code. This will override + any CPC bid set at the keyword plan ad group + level. Not applicable for negative keywords. + (negative = true) This field is Optional. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + negative (bool): + Immutable. If true, the keyword is negative. + + This field is a member of `oneof`_ ``_negative``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + keyword_plan_ad_group = proto.Field(proto.STRING, number=8, optional=True,) + id = proto.Field(proto.INT64, number=9, optional=True,) + text = proto.Field(proto.STRING, number=10, optional=True,) + match_type = proto.Field( + proto.ENUM, + number=5, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + cpc_bid_micros = proto.Field(proto.INT64, number=11, optional=True,) + negative = proto.Field(proto.BOOL, number=12, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_plan_campaign.py b/google/ads/googleads/v12/resources/types/keyword_plan_campaign.py new file mode 100644 index 000000000..c3c661e77 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_plan_campaign.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + keyword_plan_network as gage_keyword_plan_network, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanCampaign", "KeywordPlanGeoTarget",}, +) + + +class KeywordPlanCampaign(proto.Message): + r"""A Keyword Plan campaign. + Max number of keyword plan campaigns per plan allowed: 1. + + Attributes: + resource_name (str): + Immutable. The resource name of the Keyword Plan campaign. + KeywordPlanCampaign resource names have the form: + + ``customers/{customer_id}/keywordPlanCampaigns/{kp_campaign_id}`` + keyword_plan (str): + The keyword plan this campaign belongs to. + + This field is a member of `oneof`_ ``_keyword_plan``. + id (int): + Output only. The ID of the Keyword Plan + campaign. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the Keyword Plan campaign. + This field is required and should not be empty + when creating Keyword Plan campaigns. + + This field is a member of `oneof`_ ``_name``. + language_constants (Sequence[str]): + The languages targeted for the Keyword Plan + campaign. Max allowed: 1. + keyword_plan_network (google.ads.googleads.v12.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + Targeting network. + This field is required and should not be empty + when creating Keyword Plan campaigns. + cpc_bid_micros (int): + A default max cpc bid in micros, and in the + account currency, for all ad groups under the + campaign. + This field is required and should not be empty + when creating Keyword Plan campaigns. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + geo_targets (Sequence[google.ads.googleads.v12.resources.types.KeywordPlanGeoTarget]): + The geo targets. + Max number allowed: 20. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + keyword_plan = proto.Field(proto.STRING, number=9, optional=True,) + id = proto.Field(proto.INT64, number=10, optional=True,) + name = proto.Field(proto.STRING, number=11, optional=True,) + language_constants = proto.RepeatedField(proto.STRING, number=12,) + keyword_plan_network = proto.Field( + proto.ENUM, + number=6, + enum=gage_keyword_plan_network.KeywordPlanNetworkEnum.KeywordPlanNetwork, + ) + cpc_bid_micros = proto.Field(proto.INT64, number=13, optional=True,) + geo_targets = proto.RepeatedField( + proto.MESSAGE, number=8, message="KeywordPlanGeoTarget", + ) + + +class KeywordPlanGeoTarget(proto.Message): + r"""A geo target. + + Attributes: + geo_target_constant (str): + Required. The resource name of the geo + target. + + This field is a member of `oneof`_ ``_geo_target_constant``. + """ + + geo_target_constant = proto.Field(proto.STRING, number=2, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_plan_campaign_keyword.py b/google/ads/googleads/v12/resources/types/keyword_plan_campaign_keyword.py new file mode 100644 index 000000000..5ac0b4e3f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_plan_campaign_keyword.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import keyword_match_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordPlanCampaignKeyword",}, +) + + +class KeywordPlanCampaignKeyword(proto.Message): + r"""A Keyword Plan Campaign keyword. + Only negative keywords are supported for Campaign Keyword. + + Attributes: + resource_name (str): + Immutable. The resource name of the Keyword Plan Campaign + keyword. KeywordPlanCampaignKeyword resource names have the + form: + + ``customers/{customer_id}/keywordPlanCampaignKeywords/{kp_campaign_keyword_id}`` + keyword_plan_campaign (str): + The Keyword Plan campaign to which this + negative keyword belongs. + + This field is a member of `oneof`_ ``_keyword_plan_campaign``. + id (int): + Output only. The ID of the Keyword Plan + negative keyword. + + This field is a member of `oneof`_ ``_id``. + text (str): + The keyword text. + + This field is a member of `oneof`_ ``_text``. + match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + The keyword match type. + negative (bool): + Immutable. If true, the keyword is negative. + Must be set to true. Only negative campaign + keywords are supported. + + This field is a member of `oneof`_ ``_negative``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + keyword_plan_campaign = proto.Field(proto.STRING, number=8, optional=True,) + id = proto.Field(proto.INT64, number=9, optional=True,) + text = proto.Field(proto.STRING, number=10, optional=True,) + match_type = proto.Field( + proto.ENUM, + number=5, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + negative = proto.Field(proto.BOOL, number=11, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_theme_constant.py b/google/ads/googleads/v12/resources/types/keyword_theme_constant.py new file mode 100644 index 000000000..1c8ab4c12 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_theme_constant.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordThemeConstant",}, +) + + +class KeywordThemeConstant(proto.Message): + r"""A Smart Campaign keyword theme constant. + + Attributes: + resource_name (str): + Output only. The resource name of the keyword theme + constant. Keyword theme constant resource names have the + form: + + ``keywordThemeConstants/{keyword_theme_id}~{sub_keyword_theme_id}`` + country_code (str): + Output only. The ISO-3166 Alpha-2 country + code of the constant, eg. "US". To display and + query matching purpose, the keyword theme needs + to be localized. + + This field is a member of `oneof`_ ``_country_code``. + language_code (str): + Output only. The ISO-639-1 language code with + 2 letters of the constant, eg. "en". To display + and query matching purpose, the keyword theme + needs to be localized. + + This field is a member of `oneof`_ ``_language_code``. + display_name (str): + Output only. The display name of the keyword + theme or sub keyword theme. + + This field is a member of `oneof`_ ``_display_name``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + country_code = proto.Field(proto.STRING, number=2, optional=True,) + language_code = proto.Field(proto.STRING, number=3, optional=True,) + display_name = proto.Field(proto.STRING, number=4, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/keyword_view.py b/google/ads/googleads/v12/resources/types/keyword_view.py new file mode 100644 index 000000000..53eecf205 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/keyword_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"KeywordView",}, +) + + +class KeywordView(proto.Message): + r"""A keyword view. + + Attributes: + resource_name (str): + Output only. The resource name of the keyword view. Keyword + view resource names have the form: + + ``customers/{customer_id}/keywordViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/label.py b/google/ads/googleads/v12/resources/types/label.py new file mode 100644 index 000000000..a518c7dc8 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/label.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import text_label as gagc_text_label +from google.ads.googleads.v12.enums.types import label_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Label",}, +) + + +class Label(proto.Message): + r"""A label. + + Attributes: + resource_name (str): + Immutable. Name of the resource. Label resource names have + the form: ``customers/{customer_id}/labels/{label_id}`` + id (int): + Output only. ID of the label. Read only. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the label. + This field is required and should not be empty + when creating a new label. + The length of this string should be between 1 + and 80, inclusive. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v12.enums.types.LabelStatusEnum.LabelStatus): + Output only. Status of the label. Read only. + text_label (google.ads.googleads.v12.common.types.TextLabel): + A type of label displaying text on a colored + background. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=6, optional=True,) + name = proto.Field(proto.STRING, number=7, optional=True,) + status = proto.Field( + proto.ENUM, number=4, enum=label_status.LabelStatusEnum.LabelStatus, + ) + text_label = proto.Field( + proto.MESSAGE, number=5, message=gagc_text_label.TextLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/landing_page_view.py b/google/ads/googleads/v12/resources/types/landing_page_view.py new file mode 100644 index 000000000..200468251 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/landing_page_view.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"LandingPageView",}, +) + + +class LandingPageView(proto.Message): + r"""A landing page view with metrics aggregated at the unexpanded + final URL level. + + Attributes: + resource_name (str): + Output only. The resource name of the landing page view. + Landing page view resource names have the form: + + ``customers/{customer_id}/landingPageViews/{unexpanded_final_url_fingerprint}`` + unexpanded_final_url (str): + Output only. The advertiser-specified final + URL. + + This field is a member of `oneof`_ ``_unexpanded_final_url``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + unexpanded_final_url = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/language_constant.py b/google/ads/googleads/v12/resources/types/language_constant.py new file mode 100644 index 000000000..c3b65d6ef --- /dev/null +++ b/google/ads/googleads/v12/resources/types/language_constant.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"LanguageConstant",}, +) + + +class LanguageConstant(proto.Message): + r"""A language. + + Attributes: + resource_name (str): + Output only. The resource name of the language constant. + Language constant resource names have the form: + + ``languageConstants/{criterion_id}`` + id (int): + Output only. The ID of the language constant. + + This field is a member of `oneof`_ ``_id``. + code (str): + Output only. The language code, for example, "en_US", + "en_AU", "es", "fr", etc. + + This field is a member of `oneof`_ ``_code``. + name (str): + Output only. The full name of the language in + English, for example, "English (US)", "Spanish", + etc. + + This field is a member of `oneof`_ ``_name``. + targetable (bool): + Output only. Whether the language is + targetable. + + This field is a member of `oneof`_ ``_targetable``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=6, optional=True,) + code = proto.Field(proto.STRING, number=7, optional=True,) + name = proto.Field(proto.STRING, number=8, optional=True,) + targetable = proto.Field(proto.BOOL, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/lead_form_submission_data.py b/google/ads/googleads/v12/resources/types/lead_form_submission_data.py new file mode 100644 index 000000000..3dcf301a3 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/lead_form_submission_data.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import lead_form_field_user_input_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={ + "LeadFormSubmissionData", + "LeadFormSubmissionField", + "CustomLeadFormSubmissionField", + }, +) + + +class LeadFormSubmissionData(proto.Message): + r"""Data from lead form submissions. + + Attributes: + resource_name (str): + Output only. The resource name of the lead form submission + data. Lead form submission data resource names have the + form: + + ``customers/{customer_id}/leadFormSubmissionData/{lead_form_submission_data_id}`` + id (str): + Output only. ID of this lead form submission. + asset (str): + Output only. Asset associated with the + submitted lead form. + campaign (str): + Output only. Campaign associated with the + submitted lead form. + lead_form_submission_fields (Sequence[google.ads.googleads.v12.resources.types.LeadFormSubmissionField]): + Output only. Submission data associated with + a lead form. + custom_lead_form_submission_fields (Sequence[google.ads.googleads.v12.resources.types.CustomLeadFormSubmissionField]): + Output only. Submission data associated with + a custom lead form. + ad_group (str): + Output only. AdGroup associated with the + submitted lead form. + ad_group_ad (str): + Output only. AdGroupAd associated with the + submitted lead form. + gclid (str): + Output only. Google Click Id associated with + the submissed lead form. + submission_date_time (str): + Output only. The date and time at which the lead form was + submitted. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for + example, "2019-01-01 12:32:45-08:00". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.STRING, number=2,) + asset = proto.Field(proto.STRING, number=3,) + campaign = proto.Field(proto.STRING, number=4,) + lead_form_submission_fields = proto.RepeatedField( + proto.MESSAGE, number=5, message="LeadFormSubmissionField", + ) + custom_lead_form_submission_fields = proto.RepeatedField( + proto.MESSAGE, number=10, message="CustomLeadFormSubmissionField", + ) + ad_group = proto.Field(proto.STRING, number=6,) + ad_group_ad = proto.Field(proto.STRING, number=7,) + gclid = proto.Field(proto.STRING, number=8,) + submission_date_time = proto.Field(proto.STRING, number=9,) + + +class LeadFormSubmissionField(proto.Message): + r"""Fields in the submitted lead form. + + Attributes: + field_type (google.ads.googleads.v12.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): + Output only. Field type for lead form fields. + field_value (str): + Output only. Field value for lead form + fields. + """ + + field_type = proto.Field( + proto.ENUM, + number=1, + enum=lead_form_field_user_input_type.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType, + ) + field_value = proto.Field(proto.STRING, number=2,) + + +class CustomLeadFormSubmissionField(proto.Message): + r"""Fields in the submitted custom question + + Attributes: + question_text (str): + Output only. Question text for custom + question, maximum number of characters is 300. + field_value (str): + Output only. Field value for custom question + response, maximum number of characters is 70. + """ + + question_text = proto.Field(proto.STRING, number=1,) + field_value = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/life_event.py b/google/ads/googleads/v12/resources/types/life_event.py new file mode 100644 index 000000000..cbfded0bc --- /dev/null +++ b/google/ads/googleads/v12/resources/types/life_event.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + criterion_category_availability, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"LifeEvent",}, +) + + +class LifeEvent(proto.Message): + r"""A life event: a particular interest-based vertical to be + targeted to reach users when they are in the midst of important + life milestones. + + Attributes: + resource_name (str): + Output only. The resource name of the life event. Life event + resource names have the form: + + ``customers/{customer_id}/lifeEvents/{life_event_id}`` + id (int): + Output only. The ID of the life event. + name (str): + Output only. The name of the life event, for + example,"Recently Moved". + parent (str): + Output only. The parent of the life_event. + launched_to_all (bool): + Output only. True if the life event is + launched to all channels and locales. + availabilities (Sequence[google.ads.googleads.v12.common.types.CriterionCategoryAvailability]): + Output only. Availability information of the + life event. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=2,) + name = proto.Field(proto.STRING, number=3,) + parent = proto.Field(proto.STRING, number=4,) + launched_to_all = proto.Field(proto.BOOL, number=5,) + availabilities = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=criterion_category_availability.CriterionCategoryAvailability, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/location_view.py b/google/ads/googleads/v12/resources/types/location_view.py new file mode 100644 index 000000000..5e537d764 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/location_view.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"LocationView",}, +) + + +class LocationView(proto.Message): + r"""A location view summarizes the performance of campaigns by + Location criteria. + + Attributes: + resource_name (str): + Output only. The resource name of the location view. + Location view resource names have the form: + + ``customers/{customer_id}/locationViews/{campaign_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/managed_placement_view.py b/google/ads/googleads/v12/resources/types/managed_placement_view.py new file mode 100644 index 000000000..9258ecc39 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/managed_placement_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ManagedPlacementView",}, +) + + +class ManagedPlacementView(proto.Message): + r"""A managed placement view. + + Attributes: + resource_name (str): + Output only. The resource name of the Managed Placement + view. Managed placement view resource names have the form: + + ``customers/{customer_id}/managedPlacementViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/media_file.py b/google/ads/googleads/v12/resources/types/media_file.py new file mode 100644 index 000000000..9bc89808c --- /dev/null +++ b/google/ads/googleads/v12/resources/types/media_file.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import media_type +from google.ads.googleads.v12.enums.types import mime_type as gage_mime_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={ + "MediaFile", + "MediaImage", + "MediaBundle", + "MediaAudio", + "MediaVideo", + }, +) + + +class MediaFile(proto.Message): + r"""A media file. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the media file. Media file + resource names have the form: + + ``customers/{customer_id}/mediaFiles/{media_file_id}`` + id (int): + Output only. The ID of the media file. + + This field is a member of `oneof`_ ``_id``. + type_ (google.ads.googleads.v12.enums.types.MediaTypeEnum.MediaType): + Immutable. Type of the media file. + mime_type (google.ads.googleads.v12.enums.types.MimeTypeEnum.MimeType): + Output only. The mime type of the media file. + source_url (str): + Immutable. The URL of where the original + media file was downloaded from (or a file name). + Only used for media of type AUDIO and IMAGE. + + This field is a member of `oneof`_ ``_source_url``. + name (str): + Immutable. The name of the media file. The + name can be used by clients to help identify + previously uploaded media. + + This field is a member of `oneof`_ ``_name``. + file_size (int): + Output only. The size of the media file in + bytes. + + This field is a member of `oneof`_ ``_file_size``. + image (google.ads.googleads.v12.resources.types.MediaImage): + Immutable. Encapsulates an Image. + + This field is a member of `oneof`_ ``mediatype``. + media_bundle (google.ads.googleads.v12.resources.types.MediaBundle): + Immutable. A ZIP archive media the content of + which contains HTML5 assets. + + This field is a member of `oneof`_ ``mediatype``. + audio (google.ads.googleads.v12.resources.types.MediaAudio): + Output only. Encapsulates an Audio. + + This field is a member of `oneof`_ ``mediatype``. + video (google.ads.googleads.v12.resources.types.MediaVideo): + Immutable. Encapsulates a Video. + + This field is a member of `oneof`_ ``mediatype``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=12, optional=True,) + type_ = proto.Field( + proto.ENUM, number=5, enum=media_type.MediaTypeEnum.MediaType, + ) + mime_type = proto.Field( + proto.ENUM, number=6, enum=gage_mime_type.MimeTypeEnum.MimeType, + ) + source_url = proto.Field(proto.STRING, number=13, optional=True,) + name = proto.Field(proto.STRING, number=14, optional=True,) + file_size = proto.Field(proto.INT64, number=15, optional=True,) + image = proto.Field( + proto.MESSAGE, number=3, oneof="mediatype", message="MediaImage", + ) + media_bundle = proto.Field( + proto.MESSAGE, number=4, oneof="mediatype", message="MediaBundle", + ) + audio = proto.Field( + proto.MESSAGE, number=10, oneof="mediatype", message="MediaAudio", + ) + video = proto.Field( + proto.MESSAGE, number=11, oneof="mediatype", message="MediaVideo", + ) + + +class MediaImage(proto.Message): + r"""Encapsulates an Image. + + Attributes: + data (bytes): + Immutable. Raw image data. + + This field is a member of `oneof`_ ``_data``. + full_size_image_url (str): + Output only. The url to the full size version + of the image. + + This field is a member of `oneof`_ ``_full_size_image_url``. + preview_size_image_url (str): + Output only. The url to the preview size + version of the image. + + This field is a member of `oneof`_ ``_preview_size_image_url``. + """ + + data = proto.Field(proto.BYTES, number=4, optional=True,) + full_size_image_url = proto.Field(proto.STRING, number=2, optional=True,) + preview_size_image_url = proto.Field(proto.STRING, number=3, optional=True,) + + +class MediaBundle(proto.Message): + r"""Represents a ZIP archive media the content of which contains + HTML5 assets. + + Attributes: + data (bytes): + Immutable. Raw zipped data. + + This field is a member of `oneof`_ ``_data``. + url (str): + Output only. The url to access the uploaded + zipped data. For example, + https://tpc.googlesyndication.com/simgad/123 + This field is read-only. + + This field is a member of `oneof`_ ``_url``. + """ + + data = proto.Field(proto.BYTES, number=3, optional=True,) + url = proto.Field(proto.STRING, number=2, optional=True,) + + +class MediaAudio(proto.Message): + r"""Encapsulates an Audio. + + Attributes: + ad_duration_millis (int): + Output only. The duration of the Audio in + milliseconds. + + This field is a member of `oneof`_ ``_ad_duration_millis``. + """ + + ad_duration_millis = proto.Field(proto.INT64, number=2, optional=True,) + + +class MediaVideo(proto.Message): + r"""Encapsulates a Video. + + Attributes: + ad_duration_millis (int): + Output only. The duration of the Video in + milliseconds. + + This field is a member of `oneof`_ ``_ad_duration_millis``. + youtube_video_id (str): + Immutable. The YouTube video ID (as seen in + YouTube URLs). Adding prefix + "https://www.youtube.com/watch?v=" to this ID + will get the YouTube streaming URL for this + video. + + This field is a member of `oneof`_ ``_youtube_video_id``. + advertising_id_code (str): + Output only. The Advertising Digital + Identification code for this video, as defined + by the American Association of Advertising + Agencies, used mainly for television + commercials. + + This field is a member of `oneof`_ ``_advertising_id_code``. + isci_code (str): + Output only. The Industry Standard Commercial + Identifier code for this video, used mainly for + television commercials. + + This field is a member of `oneof`_ ``_isci_code``. + """ + + ad_duration_millis = proto.Field(proto.INT64, number=5, optional=True,) + youtube_video_id = proto.Field(proto.STRING, number=6, optional=True,) + advertising_id_code = proto.Field(proto.STRING, number=7, optional=True,) + isci_code = proto.Field(proto.STRING, number=8, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/merchant_center_link.py b/google/ads/googleads/v12/resources/types/merchant_center_link.py new file mode 100644 index 000000000..eadb0fb5b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/merchant_center_link.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import merchant_center_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"MerchantCenterLink",}, +) + + +class MerchantCenterLink(proto.Message): + r"""A data sharing connection, proposed or in use, + between a Google Ads Customer and a Merchant Center account. + + Attributes: + resource_name (str): + Immutable. The resource name of the merchant center link. + Merchant center link resource names have the form: + + ``customers/{customer_id}/merchantCenterLinks/{merchant_center_id}`` + id (int): + Output only. The ID of the Merchant Center + account. This field is readonly. + + This field is a member of `oneof`_ ``_id``. + merchant_center_account_name (str): + Output only. The name of the Merchant Center + account. This field is readonly. + + This field is a member of `oneof`_ ``_merchant_center_account_name``. + status (google.ads.googleads.v12.enums.types.MerchantCenterLinkStatusEnum.MerchantCenterLinkStatus): + The status of the link. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=6, optional=True,) + merchant_center_account_name = proto.Field( + proto.STRING, number=7, optional=True, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=merchant_center_link_status.MerchantCenterLinkStatusEnum.MerchantCenterLinkStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/mobile_app_category_constant.py b/google/ads/googleads/v12/resources/types/mobile_app_category_constant.py new file mode 100644 index 000000000..dd24dde57 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/mobile_app_category_constant.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"MobileAppCategoryConstant",}, +) + + +class MobileAppCategoryConstant(proto.Message): + r"""A mobile application category constant. + + Attributes: + resource_name (str): + Output only. The resource name of the mobile app category + constant. Mobile app category constant resource names have + the form: + + ``mobileAppCategoryConstants/{mobile_app_category_id}`` + id (int): + Output only. The ID of the mobile app + category constant. + + This field is a member of `oneof`_ ``_id``. + name (str): + Output only. Mobile app category name. + + This field is a member of `oneof`_ ``_name``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT32, number=4, optional=True,) + name = proto.Field(proto.STRING, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/mobile_device_constant.py b/google/ads/googleads/v12/resources/types/mobile_device_constant.py new file mode 100644 index 000000000..9fee72b08 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/mobile_device_constant.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import mobile_device_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"MobileDeviceConstant",}, +) + + +class MobileDeviceConstant(proto.Message): + r"""A mobile device constant. + + Attributes: + resource_name (str): + Output only. The resource name of the mobile device + constant. Mobile device constant resource names have the + form: + + ``mobileDeviceConstants/{criterion_id}`` + id (int): + Output only. The ID of the mobile device + constant. + + This field is a member of `oneof`_ ``_id``. + name (str): + Output only. The name of the mobile device. + + This field is a member of `oneof`_ ``_name``. + manufacturer_name (str): + Output only. The manufacturer of the mobile + device. + + This field is a member of `oneof`_ ``_manufacturer_name``. + operating_system_name (str): + Output only. The operating system of the + mobile device. + + This field is a member of `oneof`_ ``_operating_system_name``. + type_ (google.ads.googleads.v12.enums.types.MobileDeviceTypeEnum.MobileDeviceType): + Output only. The type of mobile device. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=7, optional=True,) + name = proto.Field(proto.STRING, number=8, optional=True,) + manufacturer_name = proto.Field(proto.STRING, number=9, optional=True,) + operating_system_name = proto.Field(proto.STRING, number=10, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=6, + enum=mobile_device_type.MobileDeviceTypeEnum.MobileDeviceType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/offline_user_data_job.py b/google/ads/googleads/v12/resources/types/offline_user_data_job.py new file mode 100644 index 000000000..9f904e941 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/offline_user_data_job.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import offline_user_data +from google.ads.googleads.v12.enums.types import ( + offline_user_data_job_failure_reason, +) +from google.ads.googleads.v12.enums.types import ( + offline_user_data_job_match_rate_range, +) +from google.ads.googleads.v12.enums.types import offline_user_data_job_status +from google.ads.googleads.v12.enums.types import offline_user_data_job_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"OfflineUserDataJob", "OfflineUserDataJobMetadata",}, +) + + +class OfflineUserDataJob(proto.Message): + r"""A job containing offline user data of store visitors, or user + list members that will be processed asynchronously. The uploaded + data isn't readable and the processing results of the job can + only be read using GoogleAdsService.Search/SearchStream. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the offline user data job. + Offline user data job resource names have the form: + + ``customers/{customer_id}/offlineUserDataJobs/{offline_user_data_job_id}`` + id (int): + Output only. ID of this offline user data + job. + + This field is a member of `oneof`_ ``_id``. + external_id (int): + Immutable. User specified job ID. + + This field is a member of `oneof`_ ``_external_id``. + type_ (google.ads.googleads.v12.enums.types.OfflineUserDataJobTypeEnum.OfflineUserDataJobType): + Immutable. Type of the job. + status (google.ads.googleads.v12.enums.types.OfflineUserDataJobStatusEnum.OfflineUserDataJobStatus): + Output only. Status of the job. + failure_reason (google.ads.googleads.v12.enums.types.OfflineUserDataJobFailureReasonEnum.OfflineUserDataJobFailureReason): + Output only. Reason for the processing + failure, if status is FAILED. + operation_metadata (google.ads.googleads.v12.resources.types.OfflineUserDataJobMetadata): + Output only. Metadata of offline user data + job depicting match rate range. + customer_match_user_list_metadata (google.ads.googleads.v12.common.types.CustomerMatchUserListMetadata): + Immutable. Metadata for data updates to a + CRM-based user list. + + This field is a member of `oneof`_ ``metadata``. + store_sales_metadata (google.ads.googleads.v12.common.types.StoreSalesMetadata): + Immutable. Metadata for store sales data + update. + + This field is a member of `oneof`_ ``metadata``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=9, optional=True,) + external_id = proto.Field(proto.INT64, number=10, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=offline_user_data_job_type.OfflineUserDataJobTypeEnum.OfflineUserDataJobType, + ) + status = proto.Field( + proto.ENUM, + number=5, + enum=offline_user_data_job_status.OfflineUserDataJobStatusEnum.OfflineUserDataJobStatus, + ) + failure_reason = proto.Field( + proto.ENUM, + number=6, + enum=offline_user_data_job_failure_reason.OfflineUserDataJobFailureReasonEnum.OfflineUserDataJobFailureReason, + ) + operation_metadata = proto.Field( + proto.MESSAGE, number=11, message="OfflineUserDataJobMetadata", + ) + customer_match_user_list_metadata = proto.Field( + proto.MESSAGE, + number=7, + oneof="metadata", + message=offline_user_data.CustomerMatchUserListMetadata, + ) + store_sales_metadata = proto.Field( + proto.MESSAGE, + number=8, + oneof="metadata", + message=offline_user_data.StoreSalesMetadata, + ) + + +class OfflineUserDataJobMetadata(proto.Message): + r"""Metadata of offline user data job. + + Attributes: + match_rate_range (google.ads.googleads.v12.enums.types.OfflineUserDataJobMatchRateRangeEnum.OfflineUserDataJobMatchRateRange): + Output only. Match rate of the Customer Match + user list upload. Describes the estimated match + rate when the status of the job is "RUNNING" and + final match rate when the final match rate is + available after the status of the job is + "SUCCESS/FAILED". + """ + + match_rate_range = proto.Field( + proto.ENUM, + number=1, + enum=offline_user_data_job_match_rate_range.OfflineUserDataJobMatchRateRangeEnum.OfflineUserDataJobMatchRateRange, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/operating_system_version_constant.py b/google/ads/googleads/v12/resources/types/operating_system_version_constant.py new file mode 100644 index 000000000..2662a2bcb --- /dev/null +++ b/google/ads/googleads/v12/resources/types/operating_system_version_constant.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + operating_system_version_operator_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"OperatingSystemVersionConstant",}, +) + + +class OperatingSystemVersionConstant(proto.Message): + r"""A mobile operating system version or a range of versions, depending + on ``operator_type``. List of available mobile platforms at + https://developers.google.com/google-ads/api/reference/data/codes-formats#mobile-platforms + + Attributes: + resource_name (str): + Output only. The resource name of the operating system + version constant. Operating system version constant resource + names have the form: + + ``operatingSystemVersionConstants/{criterion_id}`` + id (int): + Output only. The ID of the operating system + version. + + This field is a member of `oneof`_ ``_id``. + name (str): + Output only. Name of the operating system. + + This field is a member of `oneof`_ ``_name``. + os_major_version (int): + Output only. The OS Major Version number. + + This field is a member of `oneof`_ ``_os_major_version``. + os_minor_version (int): + Output only. The OS Minor Version number. + + This field is a member of `oneof`_ ``_os_minor_version``. + operator_type (google.ads.googleads.v12.enums.types.OperatingSystemVersionOperatorTypeEnum.OperatingSystemVersionOperatorType): + Output only. Determines whether this constant + represents a single version or a range of + versions. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=7, optional=True,) + name = proto.Field(proto.STRING, number=8, optional=True,) + os_major_version = proto.Field(proto.INT32, number=9, optional=True,) + os_minor_version = proto.Field(proto.INT32, number=10, optional=True,) + operator_type = proto.Field( + proto.ENUM, + number=6, + enum=operating_system_version_operator_type.OperatingSystemVersionOperatorTypeEnum.OperatingSystemVersionOperatorType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/paid_organic_search_term_view.py b/google/ads/googleads/v12/resources/types/paid_organic_search_term_view.py new file mode 100644 index 000000000..563c546df --- /dev/null +++ b/google/ads/googleads/v12/resources/types/paid_organic_search_term_view.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"PaidOrganicSearchTermView",}, +) + + +class PaidOrganicSearchTermView(proto.Message): + r"""A paid organic search term view providing a view of search + stats across ads and organic listings aggregated by search term + at the ad group level. + + Attributes: + resource_name (str): + Output only. The resource name of the search term view. + Search term view resource names have the form: + + ``customers/{customer_id}/paidOrganicSearchTermViews/{campaign_id}~ {ad_group_id}~{URL-base64 search term}`` + search_term (str): + Output only. The search term. + + This field is a member of `oneof`_ ``_search_term``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + search_term = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/parental_status_view.py b/google/ads/googleads/v12/resources/types/parental_status_view.py new file mode 100644 index 000000000..5c096c031 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/parental_status_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ParentalStatusView",}, +) + + +class ParentalStatusView(proto.Message): + r"""A parental status view. + + Attributes: + resource_name (str): + Output only. The resource name of the parental status view. + Parental Status view resource names have the form: + + ``customers/{customer_id}/parentalStatusViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/payments_account.py b/google/ads/googleads/v12/resources/types/payments_account.py new file mode 100644 index 000000000..1a02d2ab7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/payments_account.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"PaymentsAccount",}, +) + + +class PaymentsAccount(proto.Message): + r"""A payments account, which can be used to set up billing for + an Ads customer. + + Attributes: + resource_name (str): + Output only. The resource name of the payments account. + PaymentsAccount resource names have the form: + + ``customers/{customer_id}/paymentsAccounts/{payments_account_id}`` + payments_account_id (str): + Output only. A 16 digit ID used to identify a + payments account. + + This field is a member of `oneof`_ ``_payments_account_id``. + name (str): + Output only. The name of the payments + account. + + This field is a member of `oneof`_ ``_name``. + currency_code (str): + Output only. The currency code of the + payments account. A subset of the currency codes + derived from the ISO 4217 standard is supported. + + This field is a member of `oneof`_ ``_currency_code``. + payments_profile_id (str): + Output only. A 12 digit ID used to identify + the payments profile associated with the + payments account. + + This field is a member of `oneof`_ ``_payments_profile_id``. + secondary_payments_profile_id (str): + Output only. A secondary payments profile ID + present in uncommon situations, for example, + when a sequential liability agreement has been + arranged. + + This field is a member of `oneof`_ ``_secondary_payments_profile_id``. + paying_manager_customer (str): + Output only. Paying manager of this payment + account. + + This field is a member of `oneof`_ ``_paying_manager_customer``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + payments_account_id = proto.Field(proto.STRING, number=8, optional=True,) + name = proto.Field(proto.STRING, number=9, optional=True,) + currency_code = proto.Field(proto.STRING, number=10, optional=True,) + payments_profile_id = proto.Field(proto.STRING, number=11, optional=True,) + secondary_payments_profile_id = proto.Field( + proto.STRING, number=12, optional=True, + ) + paying_manager_customer = proto.Field( + proto.STRING, number=13, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/per_store_view.py b/google/ads/googleads/v12/resources/types/per_store_view.py new file mode 100644 index 000000000..bd7b6dc1b --- /dev/null +++ b/google/ads/googleads/v12/resources/types/per_store_view.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"PerStoreView",}, +) + + +class PerStoreView(proto.Message): + r"""An per store view. + This view provides per store impression reach and local action + conversion stats for advertisers. + + Attributes: + resource_name (str): + Output only. The resource name of the per store view. Per + Store view resource names have the form: + + ``customers/{customer_id}/perStoreViews/{place_id}`` + place_id (str): + Output only. The place ID of the per store + view. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + place_id = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/product_bidding_category_constant.py b/google/ads/googleads/v12/resources/types/product_bidding_category_constant.py new file mode 100644 index 000000000..107b87110 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/product_bidding_category_constant.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import product_bidding_category_level +from google.ads.googleads.v12.enums.types import product_bidding_category_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ProductBiddingCategoryConstant",}, +) + + +class ProductBiddingCategoryConstant(proto.Message): + r"""A Product Bidding Category. + + Attributes: + resource_name (str): + Output only. The resource name of the product bidding + category. Product bidding category resource names have the + form: + + ``productBiddingCategoryConstants/{country_code}~{level}~{id}`` + id (int): + Output only. ID of the product bidding category. + + This ID is equivalent to the google_product_category ID as + described in this article: + https://support.google.com/merchants/answer/6324436. + + This field is a member of `oneof`_ ``_id``. + country_code (str): + Output only. Two-letter upper-case country + code of the product bidding category. + + This field is a member of `oneof`_ ``_country_code``. + product_bidding_category_constant_parent (str): + Output only. Resource name of the parent + product bidding category. + + This field is a member of `oneof`_ ``_product_bidding_category_constant_parent``. + level (google.ads.googleads.v12.enums.types.ProductBiddingCategoryLevelEnum.ProductBiddingCategoryLevel): + Output only. Level of the product bidding + category. + status (google.ads.googleads.v12.enums.types.ProductBiddingCategoryStatusEnum.ProductBiddingCategoryStatus): + Output only. Status of the product bidding + category. + language_code (str): + Output only. Language code of the product + bidding category. + + This field is a member of `oneof`_ ``_language_code``. + localized_name (str): + Output only. Display value of the product bidding category + localized according to language_code. + + This field is a member of `oneof`_ ``_localized_name``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=10, optional=True,) + country_code = proto.Field(proto.STRING, number=11, optional=True,) + product_bidding_category_constant_parent = proto.Field( + proto.STRING, number=12, optional=True, + ) + level = proto.Field( + proto.ENUM, + number=5, + enum=product_bidding_category_level.ProductBiddingCategoryLevelEnum.ProductBiddingCategoryLevel, + ) + status = proto.Field( + proto.ENUM, + number=6, + enum=product_bidding_category_status.ProductBiddingCategoryStatusEnum.ProductBiddingCategoryStatus, + ) + language_code = proto.Field(proto.STRING, number=13, optional=True,) + localized_name = proto.Field(proto.STRING, number=14, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/product_group_view.py b/google/ads/googleads/v12/resources/types/product_group_view.py new file mode 100644 index 000000000..f5795b869 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/product_group_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ProductGroupView",}, +) + + +class ProductGroupView(proto.Message): + r"""A product group view. + + Attributes: + resource_name (str): + Output only. The resource name of the product group view. + Product group view resource names have the form: + + ``customers/{customer_id}/productGroupViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/recommendation.py b/google/ads/googleads/v12/resources/types/recommendation.py new file mode 100644 index 000000000..d86faf4ac --- /dev/null +++ b/google/ads/googleads/v12/resources/types/recommendation.py @@ -0,0 +1,941 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.common.types import extensions +from google.ads.googleads.v12.enums.types import keyword_match_type +from google.ads.googleads.v12.enums.types import recommendation_type +from google.ads.googleads.v12.enums.types import ( + target_cpa_opt_in_recommendation_goal, +) +from google.ads.googleads.v12.resources.types import ad as gagr_ad + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Recommendation",}, +) + + +class Recommendation(proto.Message): + r"""A recommendation. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the recommendation. + + ``customers/{customer_id}/recommendations/{recommendation_id}`` + type_ (google.ads.googleads.v12.enums.types.RecommendationTypeEnum.RecommendationType): + Output only. The type of recommendation. + impact (google.ads.googleads.v12.resources.types.Recommendation.RecommendationImpact): + Output only. The impact on account + performance as a result of applying the + recommendation. + campaign_budget (str): + Output only. The budget targeted by this recommendation. + This will be set only when the recommendation affects a + single campaign budget. + + This field will be set for the following recommendation + types: CAMPAIGN_BUDGET, FORECASTING_CAMPAIGN_BUDGET, + MARGINAL_ROI_CAMPAIGN_BUDGET, MOVE_UNUSED_BUDGET + + This field is a member of `oneof`_ ``_campaign_budget``. + campaign (str): + Output only. The campaign targeted by this recommendation. + This will be set only when the recommendation affects a + single campaign. + + This field will be set for the following recommendation + types: CALL_EXTENSION, CALLOUT_EXTENSION, + ENHANCED_CPC_OPT_IN, USE_BROAD_MATCH_KEYWORD, KEYWORD, + KEYWORD_MATCH_TYPE, + UPGRADE_LOCAL_CAMPAIGN_TO_PERFORMANCE_MAX, + MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, + OPTIMIZE_AD_ROTATION, RESPONSIVE_SEARCH_AD, + RESPONSIVE_SEARCH_AD_ASSET, SEARCH_PARTNERS_OPT_IN, + DISPLAY_EXPANSION_OPT_IN, SITELINK_EXTENSION, + TARGET_CPA_OPT_IN, TARGET_ROAS_OPT_IN, TEXT_AD, + UPGRADE_SMART_SHOPPING_CAMPAIGN_TO_PERFORMANCE_MAX , + RAISE_TARGET_CPA_BID_TOO_LOW, FORECASTING_SET_TARGET_ROAS + + This field is a member of `oneof`_ ``_campaign``. + ad_group (str): + Output only. The ad group targeted by this recommendation. + This will be set only when the recommendation affects a + single ad group. + + This field will be set for the following recommendation + types: KEYWORD, OPTIMIZE_AD_ROTATION, RESPONSIVE_SEARCH_AD, + RESPONSIVE_SEARCH_AD_ASSET, TEXT_AD + + This field is a member of `oneof`_ ``_ad_group``. + dismissed (bool): + Output only. Whether the recommendation is + dismissed or not. + + This field is a member of `oneof`_ ``_dismissed``. + campaign_budget_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CampaignBudgetRecommendation): + Output only. The campaign budget + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + forecasting_campaign_budget_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CampaignBudgetRecommendation): + Output only. The forecasting campaign budget + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + keyword_recommendation (google.ads.googleads.v12.resources.types.Recommendation.KeywordRecommendation): + Output only. The keyword recommendation. + + This field is a member of `oneof`_ ``recommendation``. + text_ad_recommendation (google.ads.googleads.v12.resources.types.Recommendation.TextAdRecommendation): + Output only. Add expanded text ad + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + target_cpa_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.TargetCpaOptInRecommendation): + Output only. The TargetCPA opt-in + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + maximize_conversions_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.MaximizeConversionsOptInRecommendation): + Output only. The MaximizeConversions Opt-In + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + enhanced_cpc_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.EnhancedCpcOptInRecommendation): + Output only. The Enhanced Cost-Per-Click + Opt-In recommendation. + + This field is a member of `oneof`_ ``recommendation``. + search_partners_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.SearchPartnersOptInRecommendation): + Output only. The Search Partners Opt-In + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + maximize_clicks_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.MaximizeClicksOptInRecommendation): + Output only. The MaximizeClicks Opt-In + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + optimize_ad_rotation_recommendation (google.ads.googleads.v12.resources.types.Recommendation.OptimizeAdRotationRecommendation): + Output only. The Optimize Ad Rotation + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + callout_extension_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CalloutExtensionRecommendation): + Output only. The Callout extension + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + sitelink_extension_recommendation (google.ads.googleads.v12.resources.types.Recommendation.SitelinkExtensionRecommendation): + Output only. The Sitelink extension + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + call_extension_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CallExtensionRecommendation): + Output only. The Call extension + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + keyword_match_type_recommendation (google.ads.googleads.v12.resources.types.Recommendation.KeywordMatchTypeRecommendation): + Output only. The keyword match type + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + move_unused_budget_recommendation (google.ads.googleads.v12.resources.types.Recommendation.MoveUnusedBudgetRecommendation): + Output only. The move unused budget + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + target_roas_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.TargetRoasOptInRecommendation): + Output only. The Target ROAS opt-in + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + responsive_search_ad_recommendation (google.ads.googleads.v12.resources.types.Recommendation.ResponsiveSearchAdRecommendation): + Output only. The add responsive search ad + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + marginal_roi_campaign_budget_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CampaignBudgetRecommendation): + Output only. The marginal ROI campaign budget + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + use_broad_match_keyword_recommendation (google.ads.googleads.v12.resources.types.Recommendation.UseBroadMatchKeywordRecommendation): + Output only. The use broad match keyword + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + responsive_search_ad_asset_recommendation (google.ads.googleads.v12.resources.types.Recommendation.ResponsiveSearchAdAssetRecommendation): + Output only. The responsive search ad asset + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + upgrade_smart_shopping_campaign_to_performance_max_recommendation (google.ads.googleads.v12.resources.types.Recommendation.UpgradeSmartShoppingCampaignToPerformanceMaxRecommendation): + Output only. The upgrade a Smart Shopping + campaign to a Performance Max campaign + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + responsive_search_ad_improve_ad_strength_recommendation (google.ads.googleads.v12.resources.types.Recommendation.ResponsiveSearchAdImproveAdStrengthRecommendation): + Output only. The responsive search ad improve + ad strength recommendation. + + This field is a member of `oneof`_ ``recommendation``. + display_expansion_opt_in_recommendation (google.ads.googleads.v12.resources.types.Recommendation.DisplayExpansionOptInRecommendation): + Output only. The Display Expansion opt-in + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + upgrade_local_campaign_to_performance_max_recommendation (google.ads.googleads.v12.resources.types.Recommendation.UpgradeLocalCampaignToPerformanceMaxRecommendation): + Output only. The upgrade a Local campaign to + a Performance Max campaign recommendation. + + This field is a member of `oneof`_ ``recommendation``. + raise_target_cpa_bid_too_low_recommendation (google.ads.googleads.v12.resources.types.Recommendation.RaiseTargetCpaBidTooLowRecommendation): + Output only. The raise target CPA bid too low + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + forecasting_set_target_roas_recommendation (google.ads.googleads.v12.resources.types.Recommendation.ForecastingSetTargetRoasRecommendation): + Output only. The forecasting set target ROAS + recommendation. + + This field is a member of `oneof`_ ``recommendation``. + """ + + class RecommendationImpact(proto.Message): + r"""The impact of making the change as described in the + recommendation. Some types of recommendations may not have + impact information. + + Attributes: + base_metrics (google.ads.googleads.v12.resources.types.Recommendation.RecommendationMetrics): + Output only. Base metrics at the time the + recommendation was generated. + potential_metrics (google.ads.googleads.v12.resources.types.Recommendation.RecommendationMetrics): + Output only. Estimated metrics if the + recommendation is applied. + """ + + base_metrics = proto.Field( + proto.MESSAGE, + number=1, + message="Recommendation.RecommendationMetrics", + ) + potential_metrics = proto.Field( + proto.MESSAGE, + number=2, + message="Recommendation.RecommendationMetrics", + ) + + class RecommendationMetrics(proto.Message): + r"""Weekly account performance metrics. For some recommendation + types, these are averaged over the past 90-day period and hence + can be fractional. + + Attributes: + impressions (float): + Output only. Number of ad impressions. + + This field is a member of `oneof`_ ``_impressions``. + clicks (float): + Output only. Number of ad clicks. + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Output only. Cost (in micros) for + advertising, in the local currency for the + account. + + This field is a member of `oneof`_ ``_cost_micros``. + conversions (float): + Output only. Number of conversions. + + This field is a member of `oneof`_ ``_conversions``. + video_views (float): + Output only. Number of video views for a + video ad campaign. + + This field is a member of `oneof`_ ``_video_views``. + """ + + impressions = proto.Field(proto.DOUBLE, number=6, optional=True,) + clicks = proto.Field(proto.DOUBLE, number=7, optional=True,) + cost_micros = proto.Field(proto.INT64, number=8, optional=True,) + conversions = proto.Field(proto.DOUBLE, number=9, optional=True,) + video_views = proto.Field(proto.DOUBLE, number=10, optional=True,) + + class CampaignBudgetRecommendation(proto.Message): + r"""The budget recommendation for budget constrained campaigns. + + Attributes: + current_budget_amount_micros (int): + Output only. The current budget amount in + micros. + + This field is a member of `oneof`_ ``_current_budget_amount_micros``. + recommended_budget_amount_micros (int): + Output only. The recommended budget amount in + micros. + + This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. + budget_options (Sequence[google.ads.googleads.v12.resources.types.Recommendation.CampaignBudgetRecommendation.CampaignBudgetRecommendationOption]): + Output only. The budget amounts and + associated impact estimates for some values of + possible budget amounts. + """ + + class CampaignBudgetRecommendationOption(proto.Message): + r"""The impact estimates for a given budget amount. + + Attributes: + budget_amount_micros (int): + Output only. The budget amount for this + option. + + This field is a member of `oneof`_ ``_budget_amount_micros``. + impact (google.ads.googleads.v12.resources.types.Recommendation.RecommendationImpact): + Output only. The impact estimate if budget is + changed to amount specified in this option. + """ + + budget_amount_micros = proto.Field( + proto.INT64, number=3, optional=True, + ) + impact = proto.Field( + proto.MESSAGE, + number=2, + message="Recommendation.RecommendationImpact", + ) + + current_budget_amount_micros = proto.Field( + proto.INT64, number=7, optional=True, + ) + recommended_budget_amount_micros = proto.Field( + proto.INT64, number=8, optional=True, + ) + budget_options = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="Recommendation.CampaignBudgetRecommendation.CampaignBudgetRecommendationOption", + ) + + class KeywordRecommendation(proto.Message): + r"""The keyword recommendation. + + Attributes: + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Output only. The recommended keyword. + recommended_cpc_bid_micros (int): + Output only. The recommended CPC + (cost-per-click) bid. + + This field is a member of `oneof`_ ``_recommended_cpc_bid_micros``. + """ + + keyword = proto.Field( + proto.MESSAGE, number=1, message=criteria.KeywordInfo, + ) + recommended_cpc_bid_micros = proto.Field( + proto.INT64, number=3, optional=True, + ) + + class TextAdRecommendation(proto.Message): + r"""The text ad recommendation. + + Attributes: + ad (google.ads.googleads.v12.resources.types.Ad): + Output only. Recommended ad. + creation_date (str): + Output only. Creation date of the recommended + ad. YYYY-MM-DD format, for example, 2018-04-17. + + This field is a member of `oneof`_ ``_creation_date``. + auto_apply_date (str): + Output only. Date, if present, is the + earliest when the recommendation will be auto + applied. YYYY-MM-DD format, for example, + 2018-04-17. + + This field is a member of `oneof`_ ``_auto_apply_date``. + """ + + ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + creation_date = proto.Field(proto.STRING, number=4, optional=True,) + auto_apply_date = proto.Field(proto.STRING, number=5, optional=True,) + + class TargetCpaOptInRecommendation(proto.Message): + r"""The Target CPA opt-in recommendation. + + Attributes: + options (Sequence[google.ads.googleads.v12.resources.types.Recommendation.TargetCpaOptInRecommendation.TargetCpaOptInRecommendationOption]): + Output only. The available goals and + corresponding options for Target CPA strategy. + recommended_target_cpa_micros (int): + Output only. The recommended average CPA + target. See required budget amount and impact of + using this recommendation in options list. + + This field is a member of `oneof`_ ``_recommended_target_cpa_micros``. + """ + + class TargetCpaOptInRecommendationOption(proto.Message): + r"""The Target CPA opt-in option with impact estimate. + + Attributes: + goal (google.ads.googleads.v12.enums.types.TargetCpaOptInRecommendationGoalEnum.TargetCpaOptInRecommendationGoal): + Output only. The goal achieved by this + option. + target_cpa_micros (int): + Output only. Average CPA target. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + required_campaign_budget_amount_micros (int): + Output only. The minimum campaign budget, in + local currency for the account, required to + achieve the target CPA. Amount is specified in + micros, where one million is equivalent to one + currency unit. + + This field is a member of `oneof`_ ``_required_campaign_budget_amount_micros``. + impact (google.ads.googleads.v12.resources.types.Recommendation.RecommendationImpact): + Output only. The impact estimate if this + option is selected. + """ + + goal = proto.Field( + proto.ENUM, + number=1, + enum=target_cpa_opt_in_recommendation_goal.TargetCpaOptInRecommendationGoalEnum.TargetCpaOptInRecommendationGoal, + ) + target_cpa_micros = proto.Field( + proto.INT64, number=5, optional=True, + ) + required_campaign_budget_amount_micros = proto.Field( + proto.INT64, number=6, optional=True, + ) + impact = proto.Field( + proto.MESSAGE, + number=4, + message="Recommendation.RecommendationImpact", + ) + + options = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Recommendation.TargetCpaOptInRecommendation.TargetCpaOptInRecommendationOption", + ) + recommended_target_cpa_micros = proto.Field( + proto.INT64, number=3, optional=True, + ) + + class MaximizeConversionsOptInRecommendation(proto.Message): + r"""The Maximize Conversions Opt-In recommendation. + + Attributes: + recommended_budget_amount_micros (int): + Output only. The recommended new budget + amount. + + This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. + """ + + recommended_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class EnhancedCpcOptInRecommendation(proto.Message): + r"""The Enhanced Cost-Per-Click Opt-In recommendation. + """ + + class SearchPartnersOptInRecommendation(proto.Message): + r"""The Search Partners Opt-In recommendation. + """ + + class MaximizeClicksOptInRecommendation(proto.Message): + r"""The Maximize Clicks opt-in recommendation. + + Attributes: + recommended_budget_amount_micros (int): + Output only. The recommended new budget + amount. Only set if the current budget is too + high. + + This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. + """ + + recommended_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class OptimizeAdRotationRecommendation(proto.Message): + r"""The Optimize Ad Rotation recommendation. + """ + + class CalloutExtensionRecommendation(proto.Message): + r"""The Callout extension recommendation. + + Attributes: + recommended_extensions (Sequence[google.ads.googleads.v12.common.types.CalloutFeedItem]): + Output only. Callout extensions recommended + to be added. + """ + + recommended_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.CalloutFeedItem, + ) + + class SitelinkExtensionRecommendation(proto.Message): + r"""The Sitelink extension recommendation. + + Attributes: + recommended_extensions (Sequence[google.ads.googleads.v12.common.types.SitelinkFeedItem]): + Output only. Sitelink extensions recommended + to be added. + """ + + recommended_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.SitelinkFeedItem, + ) + + class CallExtensionRecommendation(proto.Message): + r"""The Call extension recommendation. + + Attributes: + recommended_extensions (Sequence[google.ads.googleads.v12.common.types.CallFeedItem]): + Output only. Call extensions recommended to + be added. + """ + + recommended_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.CallFeedItem, + ) + + class KeywordMatchTypeRecommendation(proto.Message): + r"""The keyword match type recommendation. + + Attributes: + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Output only. The existing keyword where the + match type should be more broad. + recommended_match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + Output only. The recommended new match type. + """ + + keyword = proto.Field( + proto.MESSAGE, number=1, message=criteria.KeywordInfo, + ) + recommended_match_type = proto.Field( + proto.ENUM, + number=2, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + + class MoveUnusedBudgetRecommendation(proto.Message): + r"""The move unused budget recommendation. + + Attributes: + excess_campaign_budget (str): + Output only. The excess budget's resource_name. + + This field is a member of `oneof`_ ``_excess_campaign_budget``. + budget_recommendation (google.ads.googleads.v12.resources.types.Recommendation.CampaignBudgetRecommendation): + Output only. The recommendation for the + constrained budget to increase. + """ + + excess_campaign_budget = proto.Field( + proto.STRING, number=3, optional=True, + ) + budget_recommendation = proto.Field( + proto.MESSAGE, + number=2, + message="Recommendation.CampaignBudgetRecommendation", + ) + + class TargetRoasOptInRecommendation(proto.Message): + r"""The Target ROAS opt-in recommendation. + + Attributes: + recommended_target_roas (float): + Output only. The recommended target ROAS + (revenue per unit of spend). The value is + between 0.01 and 1000.0, inclusive. + + This field is a member of `oneof`_ ``_recommended_target_roas``. + required_campaign_budget_amount_micros (int): + Output only. The minimum campaign budget, in + local currency for the account, required to + achieve the target ROAS. Amount is specified in + micros, where one million is equivalent to one + currency unit. + + This field is a member of `oneof`_ ``_required_campaign_budget_amount_micros``. + """ + + recommended_target_roas = proto.Field( + proto.DOUBLE, number=1, optional=True, + ) + required_campaign_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class ResponsiveSearchAdAssetRecommendation(proto.Message): + r"""The add responsive search ad asset recommendation. + + Attributes: + current_ad (google.ads.googleads.v12.resources.types.Ad): + Output only. The current ad to be updated. + recommended_assets (google.ads.googleads.v12.resources.types.Ad): + Output only. The recommended assets. This is + populated only with the new headlines and/or + descriptions, and is otherwise empty. + """ + + current_ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + recommended_assets = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad.Ad, + ) + + class ResponsiveSearchAdImproveAdStrengthRecommendation(proto.Message): + r"""The responsive search ad improve ad strength recommendation. + + Attributes: + current_ad (google.ads.googleads.v12.resources.types.Ad): + Output only. The current ad to be updated. + recommended_ad (google.ads.googleads.v12.resources.types.Ad): + Output only. The updated ad. + """ + + current_ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + recommended_ad = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad.Ad, + ) + + class ResponsiveSearchAdRecommendation(proto.Message): + r"""The add responsive search ad recommendation. + + Attributes: + ad (google.ads.googleads.v12.resources.types.Ad): + Output only. Recommended ad. + """ + + ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + + class UseBroadMatchKeywordRecommendation(proto.Message): + r"""The use broad match keyword recommendation. + + Attributes: + keyword (Sequence[google.ads.googleads.v12.common.types.KeywordInfo]): + Output only. Sample of keywords to be + expanded to Broad Match. + suggested_keywords_count (int): + Output only. Total number of keywords to be + expanded to Broad Match in the campaign. + campaign_keywords_count (int): + Output only. Total number of keywords in the + campaign. + campaign_uses_shared_budget (bool): + Output only. Whether the associated campaign + uses a shared budget. + required_campaign_budget_amount_micros (int): + Output only. The budget recommended to avoid + becoming budget constrained after applying the + recommendation. + """ + + keyword = proto.RepeatedField( + proto.MESSAGE, number=1, message=criteria.KeywordInfo, + ) + suggested_keywords_count = proto.Field(proto.INT64, number=2,) + campaign_keywords_count = proto.Field(proto.INT64, number=3,) + campaign_uses_shared_budget = proto.Field(proto.BOOL, number=4,) + required_campaign_budget_amount_micros = proto.Field( + proto.INT64, number=5, + ) + + class UpgradeSmartShoppingCampaignToPerformanceMaxRecommendation( + proto.Message + ): + r"""The upgrade a Smart Shopping campaign to a Performance Max + campaign recommendation. + + Attributes: + merchant_id (int): + Output only. ID of Merchant Center account. + sales_country_code (str): + Output only. Country whose products from + merchant's inventory should be included. + """ + + merchant_id = proto.Field(proto.INT64, number=1,) + sales_country_code = proto.Field(proto.STRING, number=2,) + + class RaiseTargetCpaBidTooLowRecommendation(proto.Message): + r"""The raise target CPA bid too low recommendation. + + Attributes: + recommended_target_multiplier (float): + Output only. A number greater than 1.0 + indicating the factor by which we recommend the + target CPA should be increased. + + This field is a member of `oneof`_ ``_recommended_target_multiplier``. + average_target_cpa_micros (int): + Output only. The current average target CPA + of the campaign, in micros of customer local + currency. + + This field is a member of `oneof`_ ``_average_target_cpa_micros``. + """ + + recommended_target_multiplier = proto.Field( + proto.DOUBLE, number=1, optional=True, + ) + average_target_cpa_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class DisplayExpansionOptInRecommendation(proto.Message): + r"""The Display Expansion opt-in recommendation. + """ + + class UpgradeLocalCampaignToPerformanceMaxRecommendation(proto.Message): + r"""The Upgrade Local campaign to Performance Max campaign + recommendation. + + """ + + class ForecastingSetTargetRoasRecommendation(proto.Message): + r"""The forecasting set target ROAS recommendation. + + Attributes: + recommended_target_roas (float): + Output only. The recommended target ROAS + (revenue per unit of spend). The value is + between 0.01 and 1000.0, inclusive. + campaign_budget (google.ads.googleads.v12.resources.types.Recommendation.CampaignBudget): + Output only. The campaign budget. + """ + + recommended_target_roas = proto.Field(proto.DOUBLE, number=1,) + campaign_budget = proto.Field( + proto.MESSAGE, number=2, message="Recommendation.CampaignBudget", + ) + + class CampaignBudget(proto.Message): + r"""A campaign budget shared amongst various budget + recommendation types. + + Attributes: + current_amount_micros (int): + Output only. Current budget amount. + recommended_new_amount_micros (int): + Output only. Recommended budget amount. + new_start_date (str): + Output only. The date when the new budget would start being + used. This field will be set for the following + recommendation types: FORECASTING_SET_TARGET_ROAS. + YYYY-MM-DD format, for example, 2018-04-17. + """ + + current_amount_micros = proto.Field(proto.INT64, number=1,) + recommended_new_amount_micros = proto.Field(proto.INT64, number=2,) + new_start_date = proto.Field(proto.STRING, number=3,) + + resource_name = proto.Field(proto.STRING, number=1,) + type_ = proto.Field( + proto.ENUM, + number=2, + enum=recommendation_type.RecommendationTypeEnum.RecommendationType, + ) + impact = proto.Field(proto.MESSAGE, number=3, message=RecommendationImpact,) + campaign_budget = proto.Field(proto.STRING, number=24, optional=True,) + campaign = proto.Field(proto.STRING, number=25, optional=True,) + ad_group = proto.Field(proto.STRING, number=26, optional=True,) + dismissed = proto.Field(proto.BOOL, number=27, optional=True,) + campaign_budget_recommendation = proto.Field( + proto.MESSAGE, + number=4, + oneof="recommendation", + message=CampaignBudgetRecommendation, + ) + forecasting_campaign_budget_recommendation = proto.Field( + proto.MESSAGE, + number=22, + oneof="recommendation", + message=CampaignBudgetRecommendation, + ) + keyword_recommendation = proto.Field( + proto.MESSAGE, + number=8, + oneof="recommendation", + message=KeywordRecommendation, + ) + text_ad_recommendation = proto.Field( + proto.MESSAGE, + number=9, + oneof="recommendation", + message=TextAdRecommendation, + ) + target_cpa_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=10, + oneof="recommendation", + message=TargetCpaOptInRecommendation, + ) + maximize_conversions_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=11, + oneof="recommendation", + message=MaximizeConversionsOptInRecommendation, + ) + enhanced_cpc_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=12, + oneof="recommendation", + message=EnhancedCpcOptInRecommendation, + ) + search_partners_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=14, + oneof="recommendation", + message=SearchPartnersOptInRecommendation, + ) + maximize_clicks_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=15, + oneof="recommendation", + message=MaximizeClicksOptInRecommendation, + ) + optimize_ad_rotation_recommendation = proto.Field( + proto.MESSAGE, + number=16, + oneof="recommendation", + message=OptimizeAdRotationRecommendation, + ) + callout_extension_recommendation = proto.Field( + proto.MESSAGE, + number=17, + oneof="recommendation", + message=CalloutExtensionRecommendation, + ) + sitelink_extension_recommendation = proto.Field( + proto.MESSAGE, + number=18, + oneof="recommendation", + message=SitelinkExtensionRecommendation, + ) + call_extension_recommendation = proto.Field( + proto.MESSAGE, + number=19, + oneof="recommendation", + message=CallExtensionRecommendation, + ) + keyword_match_type_recommendation = proto.Field( + proto.MESSAGE, + number=20, + oneof="recommendation", + message=KeywordMatchTypeRecommendation, + ) + move_unused_budget_recommendation = proto.Field( + proto.MESSAGE, + number=21, + oneof="recommendation", + message=MoveUnusedBudgetRecommendation, + ) + target_roas_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=23, + oneof="recommendation", + message=TargetRoasOptInRecommendation, + ) + responsive_search_ad_recommendation = proto.Field( + proto.MESSAGE, + number=28, + oneof="recommendation", + message=ResponsiveSearchAdRecommendation, + ) + marginal_roi_campaign_budget_recommendation = proto.Field( + proto.MESSAGE, + number=29, + oneof="recommendation", + message=CampaignBudgetRecommendation, + ) + use_broad_match_keyword_recommendation = proto.Field( + proto.MESSAGE, + number=30, + oneof="recommendation", + message=UseBroadMatchKeywordRecommendation, + ) + responsive_search_ad_asset_recommendation = proto.Field( + proto.MESSAGE, + number=31, + oneof="recommendation", + message=ResponsiveSearchAdAssetRecommendation, + ) + upgrade_smart_shopping_campaign_to_performance_max_recommendation = proto.Field( + proto.MESSAGE, + number=32, + oneof="recommendation", + message=UpgradeSmartShoppingCampaignToPerformanceMaxRecommendation, + ) + responsive_search_ad_improve_ad_strength_recommendation = proto.Field( + proto.MESSAGE, + number=33, + oneof="recommendation", + message=ResponsiveSearchAdImproveAdStrengthRecommendation, + ) + display_expansion_opt_in_recommendation = proto.Field( + proto.MESSAGE, + number=34, + oneof="recommendation", + message=DisplayExpansionOptInRecommendation, + ) + upgrade_local_campaign_to_performance_max_recommendation = proto.Field( + proto.MESSAGE, + number=35, + oneof="recommendation", + message=UpgradeLocalCampaignToPerformanceMaxRecommendation, + ) + raise_target_cpa_bid_too_low_recommendation = proto.Field( + proto.MESSAGE, + number=36, + oneof="recommendation", + message=RaiseTargetCpaBidTooLowRecommendation, + ) + forecasting_set_target_roas_recommendation = proto.Field( + proto.MESSAGE, + number=37, + oneof="recommendation", + message=ForecastingSetTargetRoasRecommendation, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/remarketing_action.py b/google/ads/googleads/v12/resources/types/remarketing_action.py new file mode 100644 index 000000000..80b3dbb58 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/remarketing_action.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import tag_snippet + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"RemarketingAction",}, +) + + +class RemarketingAction(proto.Message): + r"""A remarketing action. A snippet of JavaScript code that will + collect the product id and the type of page people visited + (product page, shopping cart page, purchase page, general site + visit) on an advertiser's website. + + Attributes: + resource_name (str): + Immutable. The resource name of the remarketing action. + Remarketing action resource names have the form: + + ``customers/{customer_id}/remarketingActions/{remarketing_action_id}`` + id (int): + Output only. Id of the remarketing action. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the remarketing action. + This field is required and should not be empty + when creating new remarketing actions. + + This field is a member of `oneof`_ ``_name``. + tag_snippets (Sequence[google.ads.googleads.v12.common.types.TagSnippet]): + Output only. The snippets used for tracking + remarketing actions. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=5, optional=True,) + name = proto.Field(proto.STRING, number=6, optional=True,) + tag_snippets = proto.RepeatedField( + proto.MESSAGE, number=4, message=tag_snippet.TagSnippet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/search_term_view.py b/google/ads/googleads/v12/resources/types/search_term_view.py new file mode 100644 index 000000000..90edaf259 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/search_term_view.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import search_term_targeting_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"SearchTermView",}, +) + + +class SearchTermView(proto.Message): + r"""A search term view with metrics aggregated by search term at + the ad group level. + + Attributes: + resource_name (str): + Output only. The resource name of the search term view. + Search term view resource names have the form: + + ``customers/{customer_id}/searchTermViews/{campaign_id}~{ad_group_id}~{URL-base64_search_term}`` + search_term (str): + Output only. The search term. + + This field is a member of `oneof`_ ``_search_term``. + ad_group (str): + Output only. The ad group the search term + served in. + + This field is a member of `oneof`_ ``_ad_group``. + status (google.ads.googleads.v12.enums.types.SearchTermTargetingStatusEnum.SearchTermTargetingStatus): + Output only. Indicates whether the search + term is currently one of your targeted or + excluded keywords. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + search_term = proto.Field(proto.STRING, number=5, optional=True,) + ad_group = proto.Field(proto.STRING, number=6, optional=True,) + status = proto.Field( + proto.ENUM, + number=4, + enum=search_term_targeting_status.SearchTermTargetingStatusEnum.SearchTermTargetingStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/shared_criterion.py b/google/ads/googleads/v12/resources/types/shared_criterion.py new file mode 100644 index 000000000..ca9c2da83 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/shared_criterion.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import criterion_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"SharedCriterion",}, +) + + +class SharedCriterion(proto.Message): + r"""A criterion belonging to a shared set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the shared criterion. Shared + set resource names have the form: + + ``customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}`` + shared_set (str): + Immutable. The shared set to which the shared + criterion belongs. + + This field is a member of `oneof`_ ``_shared_set``. + criterion_id (int): + Output only. The ID of the criterion. + This field is ignored for mutates. + + This field is a member of `oneof`_ ``_criterion_id``. + type_ (google.ads.googleads.v12.enums.types.CriterionTypeEnum.CriterionType): + Output only. The type of the criterion. + keyword (google.ads.googleads.v12.common.types.KeywordInfo): + Immutable. Keyword. + + This field is a member of `oneof`_ ``criterion``. + youtube_video (google.ads.googleads.v12.common.types.YouTubeVideoInfo): + Immutable. YouTube Video. + + This field is a member of `oneof`_ ``criterion``. + youtube_channel (google.ads.googleads.v12.common.types.YouTubeChannelInfo): + Immutable. YouTube Channel. + + This field is a member of `oneof`_ ``criterion``. + placement (google.ads.googleads.v12.common.types.PlacementInfo): + Immutable. Placement. + + This field is a member of `oneof`_ ``criterion``. + mobile_app_category (google.ads.googleads.v12.common.types.MobileAppCategoryInfo): + Immutable. Mobile App Category. + + This field is a member of `oneof`_ ``criterion``. + mobile_application (google.ads.googleads.v12.common.types.MobileApplicationInfo): + Immutable. Mobile application. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + shared_set = proto.Field(proto.STRING, number=10, optional=True,) + criterion_id = proto.Field(proto.INT64, number=11, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=4, + enum=criterion_type.CriterionTypeEnum.CriterionType, + ) + keyword = proto.Field( + proto.MESSAGE, + number=3, + oneof="criterion", + message=criteria.KeywordInfo, + ) + youtube_video = proto.Field( + proto.MESSAGE, + number=5, + oneof="criterion", + message=criteria.YouTubeVideoInfo, + ) + youtube_channel = proto.Field( + proto.MESSAGE, + number=6, + oneof="criterion", + message=criteria.YouTubeChannelInfo, + ) + placement = proto.Field( + proto.MESSAGE, + number=7, + oneof="criterion", + message=criteria.PlacementInfo, + ) + mobile_app_category = proto.Field( + proto.MESSAGE, + number=8, + oneof="criterion", + message=criteria.MobileAppCategoryInfo, + ) + mobile_application = proto.Field( + proto.MESSAGE, + number=9, + oneof="criterion", + message=criteria.MobileApplicationInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/shared_set.py b/google/ads/googleads/v12/resources/types/shared_set.py new file mode 100644 index 000000000..57e7dbe09 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/shared_set.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import shared_set_status +from google.ads.googleads.v12.enums.types import shared_set_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"SharedSet",}, +) + + +class SharedSet(proto.Message): + r"""SharedSets are used for sharing criterion exclusions across + multiple campaigns. + + Attributes: + resource_name (str): + Immutable. The resource name of the shared set. Shared set + resource names have the form: + + ``customers/{customer_id}/sharedSets/{shared_set_id}`` + id (int): + Output only. The ID of this shared set. Read + only. + + This field is a member of `oneof`_ ``_id``. + type_ (google.ads.googleads.v12.enums.types.SharedSetTypeEnum.SharedSetType): + Immutable. The type of this shared set: each + shared set holds only a single kind of resource. + Required. Immutable. + name (str): + The name of this shared set. Required. + Shared Sets must have names that are unique + among active shared sets of the same type. + The length of this string should be between 1 + and 255 UTF-8 bytes, inclusive. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v12.enums.types.SharedSetStatusEnum.SharedSetStatus): + Output only. The status of this shared set. + Read only. + member_count (int): + Output only. The number of shared criteria + within this shared set. Read only. + + This field is a member of `oneof`_ ``_member_count``. + reference_count (int): + Output only. The number of campaigns + associated with this shared set. Read only. + + This field is a member of `oneof`_ ``_reference_count``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=8, optional=True,) + type_ = proto.Field( + proto.ENUM, + number=3, + enum=shared_set_type.SharedSetTypeEnum.SharedSetType, + ) + name = proto.Field(proto.STRING, number=9, optional=True,) + status = proto.Field( + proto.ENUM, + number=5, + enum=shared_set_status.SharedSetStatusEnum.SharedSetStatus, + ) + member_count = proto.Field(proto.INT64, number=10, optional=True,) + reference_count = proto.Field(proto.INT64, number=11, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/shopping_performance_view.py b/google/ads/googleads/v12/resources/types/shopping_performance_view.py new file mode 100644 index 000000000..a5fbf686d --- /dev/null +++ b/google/ads/googleads/v12/resources/types/shopping_performance_view.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ShoppingPerformanceView",}, +) + + +class ShoppingPerformanceView(proto.Message): + r"""Shopping performance view. + Provides Shopping campaign statistics aggregated at several + product dimension levels. Product dimension values from Merchant + Center such as brand, category, custom attributes, product + condition and product type will reflect the state of each + dimension as of the date and time when the corresponding event + was recorded. + + Attributes: + resource_name (str): + Output only. The resource name of the Shopping performance + view. Shopping performance view resource names have the + form: ``customers/{customer_id}/shoppingPerformanceView`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/smart_campaign_search_term_view.py b/google/ads/googleads/v12/resources/types/smart_campaign_search_term_view.py new file mode 100644 index 000000000..e21ef630d --- /dev/null +++ b/google/ads/googleads/v12/resources/types/smart_campaign_search_term_view.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"SmartCampaignSearchTermView",}, +) + + +class SmartCampaignSearchTermView(proto.Message): + r"""A Smart campaign search term view. + + Attributes: + resource_name (str): + Output only. The resource name of the Smart campaign search + term view. Smart campaign search term view resource names + have the form: + + ``customers/{customer_id}/smartCampaignSearchTermViews/{campaign_id}~{URL-base64_search_term}`` + search_term (str): + Output only. The search term. + campaign (str): + Output only. The Smart campaign the search + term served in. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + search_term = proto.Field(proto.STRING, number=2,) + campaign = proto.Field(proto.STRING, number=3,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/smart_campaign_setting.py b/google/ads/googleads/v12/resources/types/smart_campaign_setting.py new file mode 100644 index 000000000..96839d50f --- /dev/null +++ b/google/ads/googleads/v12/resources/types/smart_campaign_setting.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"SmartCampaignSetting",}, +) + + +class SmartCampaignSetting(proto.Message): + r"""Settings for configuring Smart campaigns. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the Smart campaign setting. + Smart campaign setting resource names have the form: + + ``customers/{customer_id}/smartCampaignSettings/{campaign_id}`` + campaign (str): + Output only. The campaign to which these + settings apply. + phone_number (google.ads.googleads.v12.resources.types.SmartCampaignSetting.PhoneNumber): + Phone number and country code. + advertising_language_code (str): + The ISO-639-1 language code to advertise in. + final_url (str): + The user-provided landing page URL for this + Campaign. + + This field is a member of `oneof`_ ``landing_page``. + ad_optimized_business_profile_setting (google.ads.googleads.v12.resources.types.SmartCampaignSetting.AdOptimizedBusinessProfileSetting): + Settings for configuring a business profile + optimized for ads as this campaign's landing + page. This campaign must be linked to a + business profile to use this option. For more + information on this feature, consult + https://support.google.com/google-ads/answer/9827068. + + This field is a member of `oneof`_ ``landing_page``. + business_name (str): + The name of the business. + + This field is a member of `oneof`_ ``business_setting``. + business_profile_location (str): + The resource name of a Business Profile location. Business + Profile location resource names can be fetched through the + Business Profile API and adhere to the following format: + ``locations/{locationId}``. + + See the [Business Profile API] + (https://developers.google.com/my-business/reference/businessinformation/rest/v1/accounts.locations) + for additional details. + + This field is a member of `oneof`_ ``business_setting``. + """ + + class PhoneNumber(proto.Message): + r"""Phone number and country code in smart campaign settings. + + Attributes: + phone_number (str): + Phone number of the smart campaign. + + This field is a member of `oneof`_ ``_phone_number``. + country_code (str): + Upper-case, two-letter country code as + defined by ISO-3166. + + This field is a member of `oneof`_ ``_country_code``. + """ + + phone_number = proto.Field(proto.STRING, number=1, optional=True,) + country_code = proto.Field(proto.STRING, number=2, optional=True,) + + class AdOptimizedBusinessProfileSetting(proto.Message): + r"""Settings for configuring a business profile optimized for ads + as this campaign's landing page. + + Attributes: + include_lead_form (bool): + Enabling a lead form on your business profile + enables prospective customers to contact your + business by filling out a simple form, and + you'll receive their information through email. + + This field is a member of `oneof`_ ``_include_lead_form``. + """ + + include_lead_form = proto.Field(proto.BOOL, number=1, optional=True,) + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + phone_number = proto.Field(proto.MESSAGE, number=3, message=PhoneNumber,) + advertising_language_code = proto.Field(proto.STRING, number=7,) + final_url = proto.Field(proto.STRING, number=8, oneof="landing_page",) + ad_optimized_business_profile_setting = proto.Field( + proto.MESSAGE, + number=9, + oneof="landing_page", + message=AdOptimizedBusinessProfileSetting, + ) + business_name = proto.Field( + proto.STRING, number=5, oneof="business_setting", + ) + business_profile_location = proto.Field( + proto.STRING, number=10, oneof="business_setting", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/third_party_app_analytics_link.py b/google/ads/googleads/v12/resources/types/third_party_app_analytics_link.py new file mode 100644 index 000000000..f89aa90ca --- /dev/null +++ b/google/ads/googleads/v12/resources/types/third_party_app_analytics_link.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"ThirdPartyAppAnalyticsLink",}, +) + + +class ThirdPartyAppAnalyticsLink(proto.Message): + r"""A data sharing connection, allowing the import of third party + app analytics into a Google Ads Customer. + + Attributes: + resource_name (str): + Immutable. The resource name of the third party app + analytics link. Third party app analytics link resource + names have the form: + + ``customers/{customer_id}/thirdPartyAppAnalyticsLinks/{account_link_id}`` + shareable_link_id (str): + Output only. The shareable link ID that + should be provided to the third party when + setting up app analytics. This is able to be + regenerated using regenerate method in the + ThirdPartyAppAnalyticsLinkService. + + This field is a member of `oneof`_ ``_shareable_link_id``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + shareable_link_id = proto.Field(proto.STRING, number=3, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/topic_constant.py b/google/ads/googleads/v12/resources/types/topic_constant.py new file mode 100644 index 000000000..194312fc1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/topic_constant.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"TopicConstant",}, +) + + +class TopicConstant(proto.Message): + r"""Use topics to target or exclude placements in the Google + Display Network based on the category into which the placement + falls (for example, "Pets & Animals/Pets/Dogs"). + + Attributes: + resource_name (str): + Output only. The resource name of the topic constant. topic + constant resource names have the form: + + ``topicConstants/{topic_id}`` + id (int): + Output only. The ID of the topic. + + This field is a member of `oneof`_ ``_id``. + topic_constant_parent (str): + Output only. Resource name of parent of the + topic constant. + + This field is a member of `oneof`_ ``_topic_constant_parent``. + path (Sequence[str]): + Output only. The category to target or + exclude. Each subsequent element in the array + describes a more specific sub-category. For + example, {"Pets & Animals", "Pets", "Dogs"} + represents the "Pets & Animals/Pets/Dogs" + category. List of available topic categories at + https://developers.google.com/adwords/api/docs/appendix/verticals + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=5, optional=True,) + topic_constant_parent = proto.Field(proto.STRING, number=6, optional=True,) + path = proto.RepeatedField(proto.STRING, number=7,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/topic_view.py b/google/ads/googleads/v12/resources/types/topic_view.py new file mode 100644 index 000000000..a63e1901a --- /dev/null +++ b/google/ads/googleads/v12/resources/types/topic_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"TopicView",}, +) + + +class TopicView(proto.Message): + r"""A topic view. + + Attributes: + resource_name (str): + Output only. The resource name of the topic view. Topic view + resource names have the form: + + ``customers/{customer_id}/topicViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/user_interest.py b/google/ads/googleads/v12/resources/types/user_interest.py new file mode 100644 index 000000000..de5139978 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/user_interest.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ( + criterion_category_availability, +) +from google.ads.googleads.v12.enums.types import user_interest_taxonomy_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"UserInterest",}, +) + + +class UserInterest(proto.Message): + r"""A user interest: a particular interest-based vertical to be + targeted. + + Attributes: + resource_name (str): + Output only. The resource name of the user interest. User + interest resource names have the form: + + ``customers/{customer_id}/userInterests/{user_interest_id}`` + taxonomy_type (google.ads.googleads.v12.enums.types.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType): + Output only. Taxonomy type of the user + interest. + user_interest_id (int): + Output only. The ID of the user interest. + + This field is a member of `oneof`_ ``_user_interest_id``. + name (str): + Output only. The name of the user interest. + + This field is a member of `oneof`_ ``_name``. + user_interest_parent (str): + Output only. The parent of the user interest. + + This field is a member of `oneof`_ ``_user_interest_parent``. + launched_to_all (bool): + Output only. True if the user interest is + launched to all channels and locales. + + This field is a member of `oneof`_ ``_launched_to_all``. + availabilities (Sequence[google.ads.googleads.v12.common.types.CriterionCategoryAvailability]): + Output only. Availability information of the + user interest. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + taxonomy_type = proto.Field( + proto.ENUM, + number=2, + enum=user_interest_taxonomy_type.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType, + ) + user_interest_id = proto.Field(proto.INT64, number=8, optional=True,) + name = proto.Field(proto.STRING, number=9, optional=True,) + user_interest_parent = proto.Field(proto.STRING, number=10, optional=True,) + launched_to_all = proto.Field(proto.BOOL, number=11, optional=True,) + availabilities = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=criterion_category_availability.CriterionCategoryAvailability, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/user_list.py b/google/ads/googleads/v12/resources/types/user_list.py new file mode 100644 index 000000000..d1411cea1 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/user_list.py @@ -0,0 +1,270 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import user_lists +from google.ads.googleads.v12.enums.types import ( + access_reason as gage_access_reason, +) +from google.ads.googleads.v12.enums.types import user_list_access_status +from google.ads.googleads.v12.enums.types import user_list_closing_reason +from google.ads.googleads.v12.enums.types import user_list_membership_status +from google.ads.googleads.v12.enums.types import user_list_size_range +from google.ads.googleads.v12.enums.types import user_list_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"UserList",}, +) + + +class UserList(proto.Message): + r"""A user list. This is a list of users a customer may target. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the user list. User list + resource names have the form: + + ``customers/{customer_id}/userLists/{user_list_id}`` + id (int): + Output only. Id of the user list. + + This field is a member of `oneof`_ ``_id``. + read_only (bool): + Output only. An option that indicates if a + user may edit a list. Depends on the list + ownership and list type. For example, external + remarketing user lists are not editable. + + This field is read-only. + + This field is a member of `oneof`_ ``_read_only``. + name (str): + Name of this user list. Depending on its access_reason, the + user list name may not be unique (for example, if + access_reason=SHARED) + + This field is a member of `oneof`_ ``_name``. + description (str): + Description of this user list. + + This field is a member of `oneof`_ ``_description``. + membership_status (google.ads.googleads.v12.enums.types.UserListMembershipStatusEnum.UserListMembershipStatus): + Membership status of this user list. + Indicates whether a user list is open or active. + Only open user lists can accumulate more users + and can be targeted to. + integration_code (str): + An ID from external system. It is used by + user list sellers to correlate IDs on their + systems. + + This field is a member of `oneof`_ ``_integration_code``. + membership_life_span (int): + Number of days a user's cookie stays on your list since its + most recent addition to the list. This field must be between + 0 and 540 inclusive. However, for CRM based userlists, this + field can be set to 10000 which means no expiration. + + It'll be ignored for logical_user_list. + + This field is a member of `oneof`_ ``_membership_life_span``. + size_for_display (int): + Output only. Estimated number of users in + this user list, on the Google Display Network. + This value is null if the number of users has + not yet been determined. + This field is read-only. + + This field is a member of `oneof`_ ``_size_for_display``. + size_range_for_display (google.ads.googleads.v12.enums.types.UserListSizeRangeEnum.UserListSizeRange): + Output only. Size range in terms of number of + users of the UserList, on the Google Display + Network. + This field is read-only. + size_for_search (int): + Output only. Estimated number of users in + this user list in the google.com domain. These + are the users available for targeting in Search + campaigns. This value is null if the number of + users has not yet been determined. + This field is read-only. + + This field is a member of `oneof`_ ``_size_for_search``. + size_range_for_search (google.ads.googleads.v12.enums.types.UserListSizeRangeEnum.UserListSizeRange): + Output only. Size range in terms of number of + users of the UserList, for Search ads. + This field is read-only. + type_ (google.ads.googleads.v12.enums.types.UserListTypeEnum.UserListType): + Output only. Type of this list. + This field is read-only. + closing_reason (google.ads.googleads.v12.enums.types.UserListClosingReasonEnum.UserListClosingReason): + Indicating the reason why this user list + membership status is closed. It is only + populated on lists that were automatically + closed due to inactivity, and will be cleared + once the list membership status becomes open. + access_reason (google.ads.googleads.v12.enums.types.AccessReasonEnum.AccessReason): + Output only. Indicates the reason this + account has been granted access to the list. The + reason can be SHARED, OWNED, LICENSED or + SUBSCRIBED. + This field is read-only. + account_user_list_status (google.ads.googleads.v12.enums.types.UserListAccessStatusEnum.UserListAccessStatus): + Indicates if this share is still enabled. + When a UserList is shared with the user this + field is set to ENABLED. Later the userList + owner can decide to revoke the share and make it + DISABLED. + The default value of this field is set to + ENABLED. + eligible_for_search (bool): + Indicates if this user list is eligible for + Google Search Network. + + This field is a member of `oneof`_ ``_eligible_for_search``. + eligible_for_display (bool): + Output only. Indicates this user list is + eligible for Google Display Network. + This field is read-only. + + This field is a member of `oneof`_ ``_eligible_for_display``. + match_rate_percentage (int): + Output only. Indicates match rate for Customer Match lists. + The range of this field is [0-100]. This will be null for + other list types or when it's not possible to calculate the + match rate. + + This field is read-only. + + This field is a member of `oneof`_ ``_match_rate_percentage``. + crm_based_user_list (google.ads.googleads.v12.common.types.CrmBasedUserListInfo): + User list of CRM users provided by the + advertiser. + + This field is a member of `oneof`_ ``user_list``. + similar_user_list (google.ads.googleads.v12.common.types.SimilarUserListInfo): + Output only. User list which are similar to + users from another UserList. These lists are + readonly and automatically created by google. + + This field is a member of `oneof`_ ``user_list``. + rule_based_user_list (google.ads.googleads.v12.common.types.RuleBasedUserListInfo): + User list generated by a rule. + + This field is a member of `oneof`_ ``user_list``. + logical_user_list (google.ads.googleads.v12.common.types.LogicalUserListInfo): + User list that is a custom combination of + user lists and user interests. + + This field is a member of `oneof`_ ``user_list``. + basic_user_list (google.ads.googleads.v12.common.types.BasicUserListInfo): + User list targeting as a collection of + conversion or remarketing actions. + + This field is a member of `oneof`_ ``user_list``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.INT64, number=25, optional=True,) + read_only = proto.Field(proto.BOOL, number=26, optional=True,) + name = proto.Field(proto.STRING, number=27, optional=True,) + description = proto.Field(proto.STRING, number=28, optional=True,) + membership_status = proto.Field( + proto.ENUM, + number=6, + enum=user_list_membership_status.UserListMembershipStatusEnum.UserListMembershipStatus, + ) + integration_code = proto.Field(proto.STRING, number=29, optional=True,) + membership_life_span = proto.Field(proto.INT64, number=30, optional=True,) + size_for_display = proto.Field(proto.INT64, number=31, optional=True,) + size_range_for_display = proto.Field( + proto.ENUM, + number=10, + enum=user_list_size_range.UserListSizeRangeEnum.UserListSizeRange, + ) + size_for_search = proto.Field(proto.INT64, number=32, optional=True,) + size_range_for_search = proto.Field( + proto.ENUM, + number=12, + enum=user_list_size_range.UserListSizeRangeEnum.UserListSizeRange, + ) + type_ = proto.Field( + proto.ENUM, + number=13, + enum=user_list_type.UserListTypeEnum.UserListType, + ) + closing_reason = proto.Field( + proto.ENUM, + number=14, + enum=user_list_closing_reason.UserListClosingReasonEnum.UserListClosingReason, + ) + access_reason = proto.Field( + proto.ENUM, + number=15, + enum=gage_access_reason.AccessReasonEnum.AccessReason, + ) + account_user_list_status = proto.Field( + proto.ENUM, + number=16, + enum=user_list_access_status.UserListAccessStatusEnum.UserListAccessStatus, + ) + eligible_for_search = proto.Field(proto.BOOL, number=33, optional=True,) + eligible_for_display = proto.Field(proto.BOOL, number=34, optional=True,) + match_rate_percentage = proto.Field(proto.INT32, number=24, optional=True,) + crm_based_user_list = proto.Field( + proto.MESSAGE, + number=19, + oneof="user_list", + message=user_lists.CrmBasedUserListInfo, + ) + similar_user_list = proto.Field( + proto.MESSAGE, + number=20, + oneof="user_list", + message=user_lists.SimilarUserListInfo, + ) + rule_based_user_list = proto.Field( + proto.MESSAGE, + number=21, + oneof="user_list", + message=user_lists.RuleBasedUserListInfo, + ) + logical_user_list = proto.Field( + proto.MESSAGE, + number=22, + oneof="user_list", + message=user_lists.LogicalUserListInfo, + ) + basic_user_list = proto.Field( + proto.MESSAGE, + number=23, + oneof="user_list", + message=user_lists.BasicUserListInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/user_location_view.py b/google/ads/googleads/v12/resources/types/user_location_view.py new file mode 100644 index 000000000..2d94059ed --- /dev/null +++ b/google/ads/googleads/v12/resources/types/user_location_view.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"UserLocationView",}, +) + + +class UserLocationView(proto.Message): + r"""A user location view. + User Location View includes all metrics aggregated at the + country level, one row per country. It reports metrics at the + actual physical location of the user by targeted or not targeted + location. If other segment fields are used, you may get more + than one row per country. + + Attributes: + resource_name (str): + Output only. The resource name of the user location view. + UserLocation view resource names have the form: + + ``customers/{customer_id}/userLocationViews/{country_criterion_id}~{targeting_location}`` + country_criterion_id (int): + Output only. Criterion Id for the country. + + This field is a member of `oneof`_ ``_country_criterion_id``. + targeting_location (bool): + Output only. Indicates whether location was + targeted or not. + + This field is a member of `oneof`_ ``_targeting_location``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + country_criterion_id = proto.Field(proto.INT64, number=4, optional=True,) + targeting_location = proto.Field(proto.BOOL, number=5, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/video.py b/google/ads/googleads/v12/resources/types/video.py new file mode 100644 index 000000000..809c642dd --- /dev/null +++ b/google/ads/googleads/v12/resources/types/video.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"Video",}, +) + + +class Video(proto.Message): + r"""A video. + + Attributes: + resource_name (str): + Output only. The resource name of the video. Video resource + names have the form: + + ``customers/{customer_id}/videos/{video_id}`` + id (str): + Output only. The ID of the video. + + This field is a member of `oneof`_ ``_id``. + channel_id (str): + Output only. The owner channel id of the + video. + + This field is a member of `oneof`_ ``_channel_id``. + duration_millis (int): + Output only. The duration of the video in + milliseconds. + + This field is a member of `oneof`_ ``_duration_millis``. + title (str): + Output only. The title of the video. + + This field is a member of `oneof`_ ``_title``. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.STRING, number=6, optional=True,) + channel_id = proto.Field(proto.STRING, number=7, optional=True,) + duration_millis = proto.Field(proto.INT64, number=8, optional=True,) + title = proto.Field(proto.STRING, number=9, optional=True,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/resources/types/webpage_view.py b/google/ads/googleads/v12/resources/types/webpage_view.py new file mode 100644 index 000000000..8359497d7 --- /dev/null +++ b/google/ads/googleads/v12/resources/types/webpage_view.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.resources", + marshal="google.ads.googleads.v12", + manifest={"WebpageView",}, +) + + +class WebpageView(proto.Message): + r"""A webpage view. + + Attributes: + resource_name (str): + Output only. The resource name of the webpage view. Webpage + view resource names have the form: + + ``customers/{customer_id}/webpageViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/__init__.py b/google/ads/googleads/v12/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/services/services/__init__.py b/google/ads/googleads/v12/services/services/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/services/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/services/services/account_budget_proposal_service/__init__.py b/google/ads/googleads/v12/services/services/account_budget_proposal_service/__init__.py new file mode 100644 index 000000000..9c82b1171 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_budget_proposal_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AccountBudgetProposalServiceClient + +__all__ = ("AccountBudgetProposalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/account_budget_proposal_service/client.py b/google/ads/googleads/v12/services/services/account_budget_proposal_service/client.py new file mode 100644 index 000000000..899548d42 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_budget_proposal_service/client.py @@ -0,0 +1,543 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + account_budget_proposal_service, +) +from .transports.base import ( + AccountBudgetProposalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AccountBudgetProposalServiceGrpcTransport + + +class AccountBudgetProposalServiceClientMeta(type): + """Metaclass for the AccountBudgetProposalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AccountBudgetProposalServiceTransport]] + _transport_registry["grpc"] = AccountBudgetProposalServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AccountBudgetProposalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AccountBudgetProposalServiceClient( + metaclass=AccountBudgetProposalServiceClientMeta +): + """A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AccountBudgetProposalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountBudgetProposalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def account_budget_path(customer_id: str, account_budget_id: str,) -> str: + """Returns a fully-qualified account_budget string.""" + return "customers/{customer_id}/accountBudgets/{account_budget_id}".format( + customer_id=customer_id, account_budget_id=account_budget_id, + ) + + @staticmethod + def parse_account_budget_path(path: str) -> Dict[str, str]: + """Parses a account_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_proposal_path( + customer_id: str, account_budget_proposal_id: str, + ) -> str: + """Returns a fully-qualified account_budget_proposal string.""" + return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( + customer_id=customer_id, + account_budget_proposal_id=account_budget_proposal_id, + ) + + @staticmethod + def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: + """Parses a account_budget_proposal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def billing_setup_path(customer_id: str, billing_setup_id: str,) -> str: + """Returns a fully-qualified billing_setup string.""" + return "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, billing_setup_id=billing_setup_id, + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, AccountBudgetProposalServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account budget proposal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AccountBudgetProposalServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AccountBudgetProposalServiceTransport): + # transport is a AccountBudgetProposalServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_account_budget_proposal( + self, + request: Union[ + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + dict, + ] = None, + *, + customer_id: str = None, + operation: account_budget_proposal_service.AccountBudgetProposalOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> account_budget_proposal_service.MutateAccountBudgetProposalResponse: + r"""Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAccountBudgetProposalRequest, dict]): + The request object. Request message for + [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v12.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.AccountBudgetProposalOperation): + Required. The operation to perform on + an individual account-level budget + proposal. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAccountBudgetProposalResponse: + Response message for account-level + budget mutate operations. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a account_budget_proposal_service.MutateAccountBudgetProposalRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + ): + request = account_budget_proposal_service.MutateAccountBudgetProposalRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_account_budget_proposal + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AccountBudgetProposalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/__init__.py b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/__init__.py new file mode 100644 index 000000000..3aeb9a73b --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AccountBudgetProposalServiceTransport +from .grpc import AccountBudgetProposalServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AccountBudgetProposalServiceTransport]] +_transport_registry["grpc"] = AccountBudgetProposalServiceGrpcTransport + +__all__ = ( + "AccountBudgetProposalServiceTransport", + "AccountBudgetProposalServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/base.py b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/base.py new file mode 100644 index 000000000..274a13a23 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + account_budget_proposal_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AccountBudgetProposalServiceTransport(abc.ABC): + """Abstract transport class for AccountBudgetProposalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_account_budget_proposal: gapic_v1.method.wrap_method( + self.mutate_account_budget_proposal, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_account_budget_proposal( + self, + ) -> Callable[ + [account_budget_proposal_service.MutateAccountBudgetProposalRequest], + Union[ + account_budget_proposal_service.MutateAccountBudgetProposalResponse, + Awaitable[ + account_budget_proposal_service.MutateAccountBudgetProposalResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AccountBudgetProposalServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/grpc.py b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/grpc.py new file mode 100644 index 000000000..c75e881a3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_budget_proposal_service/transports/grpc.py @@ -0,0 +1,290 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + account_budget_proposal_service, +) +from .base import AccountBudgetProposalServiceTransport, DEFAULT_CLIENT_INFO + + +class AccountBudgetProposalServiceGrpcTransport( + AccountBudgetProposalServiceTransport +): + """gRPC backend transport for AccountBudgetProposalService. + + A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_account_budget_proposal( + self, + ) -> Callable[ + [account_budget_proposal_service.MutateAccountBudgetProposalRequest], + account_budget_proposal_service.MutateAccountBudgetProposalResponse, + ]: + r"""Return a callable for the mutate account budget proposal method over gRPC. + + Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAccountBudgetProposalRequest], + ~.MutateAccountBudgetProposalResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_budget_proposal" not in self._stubs: + self._stubs[ + "mutate_account_budget_proposal" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AccountBudgetProposalService/MutateAccountBudgetProposal", + request_serializer=account_budget_proposal_service.MutateAccountBudgetProposalRequest.serialize, + response_deserializer=account_budget_proposal_service.MutateAccountBudgetProposalResponse.deserialize, + ) + return self._stubs["mutate_account_budget_proposal"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AccountBudgetProposalServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/account_link_service/__init__.py b/google/ads/googleads/v12/services/services/account_link_service/__init__.py new file mode 100644 index 000000000..3165e8d06 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AccountLinkServiceClient + +__all__ = ("AccountLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/account_link_service/client.py b/google/ads/googleads/v12/services/services/account_link_service/client.py new file mode 100644 index 000000000..6559e4a24 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_link_service/client.py @@ -0,0 +1,600 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import ( + account_link as gagr_account_link, +) +from google.ads.googleads.v12.services.types import account_link_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AccountLinkServiceGrpcTransport + + +class AccountLinkServiceClientMeta(type): + """Metaclass for the AccountLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AccountLinkServiceTransport]] + _transport_registry["grpc"] = AccountLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AccountLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AccountLinkServiceClient(metaclass=AccountLinkServiceClientMeta): + """This service allows management of links between Google Ads + accounts and other accounts. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def account_link_path(customer_id: str, account_link_id: str,) -> str: + """Returns a fully-qualified account_link string.""" + return "customers/{customer_id}/accountLinks/{account_link_id}".format( + customer_id=customer_id, account_link_id=account_link_id, + ) + + @staticmethod + def parse_account_link_path(path: str) -> Dict[str, str]: + """Parses a account_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AccountLinkServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AccountLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AccountLinkServiceTransport): + # transport is a AccountLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def create_account_link( + self, + request: Union[ + account_link_service.CreateAccountLinkRequest, dict + ] = None, + *, + customer_id: str = None, + account_link: gagr_account_link.AccountLink = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> account_link_service.CreateAccountLinkResponse: + r"""Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.CreateAccountLinkRequest, dict]): + The request object. Request message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v12.services.AccountLinkService.CreateAccountLink]. + customer_id (str): + Required. The ID of the customer for + which the account link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + account_link (google.ads.googleads.v12.resources.types.AccountLink): + Required. The account link to be + created. + + This corresponds to the ``account_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.CreateAccountLinkResponse: + Response message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v12.services.AccountLinkService.CreateAccountLink]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, account_link]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a account_link_service.CreateAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, account_link_service.CreateAccountLinkRequest + ): + request = account_link_service.CreateAccountLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if account_link is not None: + request.account_link = account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate_account_link( + self, + request: Union[ + account_link_service.MutateAccountLinkRequest, dict + ] = None, + *, + customer_id: str = None, + operation: account_link_service.AccountLinkOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> account_link_service.MutateAccountLinkResponse: + r"""Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAccountLinkRequest, dict]): + The request object. Request message for + [AccountLinkService.MutateAccountLink][google.ads.googleads.v12.services.AccountLinkService.MutateAccountLink]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.AccountLinkOperation): + Required. The operation to perform on + the link. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAccountLinkResponse: + Response message for account link + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a account_link_service.MutateAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, account_link_service.MutateAccountLinkRequest + ): + request = account_link_service.MutateAccountLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AccountLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/account_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/account_link_service/transports/__init__.py new file mode 100644 index 000000000..a111cb038 --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AccountLinkServiceTransport +from .grpc import AccountLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AccountLinkServiceTransport]] +_transport_registry["grpc"] = AccountLinkServiceGrpcTransport + +__all__ = ( + "AccountLinkServiceTransport", + "AccountLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/account_link_service/transports/base.py b/google/ads/googleads/v12/services/services/account_link_service/transports/base.py new file mode 100644 index 000000000..4131a3bcb --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_link_service/transports/base.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import account_link_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AccountLinkServiceTransport(abc.ABC): + """Abstract transport class for AccountLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_account_link: gapic_v1.method.wrap_method( + self.create_account_link, + default_timeout=None, + client_info=client_info, + ), + self.mutate_account_link: gapic_v1.method.wrap_method( + self.mutate_account_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def create_account_link( + self, + ) -> Callable[ + [account_link_service.CreateAccountLinkRequest], + Union[ + account_link_service.CreateAccountLinkResponse, + Awaitable[account_link_service.CreateAccountLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def mutate_account_link( + self, + ) -> Callable[ + [account_link_service.MutateAccountLinkRequest], + Union[ + account_link_service.MutateAccountLinkResponse, + Awaitable[account_link_service.MutateAccountLinkResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AccountLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/account_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/account_link_service/transports/grpc.py new file mode 100644 index 000000000..e4934f18e --- /dev/null +++ b/google/ads/googleads/v12/services/services/account_link_service/transports/grpc.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import account_link_service +from .base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class AccountLinkServiceGrpcTransport(AccountLinkServiceTransport): + """gRPC backend transport for AccountLinkService. + + This service allows management of links between Google Ads + accounts and other accounts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def create_account_link( + self, + ) -> Callable[ + [account_link_service.CreateAccountLinkRequest], + account_link_service.CreateAccountLinkResponse, + ]: + r"""Return a callable for the create account link method over gRPC. + + Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Returns: + Callable[[~.CreateAccountLinkRequest], + ~.CreateAccountLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_account_link" not in self._stubs: + self._stubs["create_account_link"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AccountLinkService/CreateAccountLink", + request_serializer=account_link_service.CreateAccountLinkRequest.serialize, + response_deserializer=account_link_service.CreateAccountLinkResponse.deserialize, + ) + return self._stubs["create_account_link"] + + @property + def mutate_account_link( + self, + ) -> Callable[ + [account_link_service.MutateAccountLinkRequest], + account_link_service.MutateAccountLinkResponse, + ]: + r"""Return a callable for the mutate account link method over gRPC. + + Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAccountLinkRequest], + ~.MutateAccountLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_link" not in self._stubs: + self._stubs["mutate_account_link"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AccountLinkService/MutateAccountLink", + request_serializer=account_link_service.MutateAccountLinkRequest.serialize, + response_deserializer=account_link_service.MutateAccountLinkResponse.deserialize, + ) + return self._stubs["mutate_account_link"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AccountLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_label_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/__init__.py new file mode 100644 index 000000000..d5502544e --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupAdLabelServiceClient + +__all__ = ("AdGroupAdLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_label_service/client.py b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/client.py new file mode 100644 index 000000000..9a8f5c898 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/client.py @@ -0,0 +1,529 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAdLabelServiceGrpcTransport + + +class AdGroupAdLabelServiceClientMeta(type): + """Metaclass for the AdGroupAdLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAdLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupAdLabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupAdLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAdLabelServiceClient(metaclass=AdGroupAdLabelServiceClientMeta): + """Service to manage labels on ad group ads.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAdLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_ad_path( + customer_id: str, ad_group_id: str, ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, ad_group_id: str, ad_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupAdLabelServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupAdLabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupAdLabelServiceTransport): + # transport is a AdGroupAdLabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_ad_labels( + self, + request: Union[ + ad_group_ad_label_service.MutateAdGroupAdLabelsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_ad_label_service.AdGroupAdLabelOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_ad_label_service.MutateAdGroupAdLabelsResponse: + r"""Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupAdLabelsRequest, dict]): + The request object. Request message for + [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v12.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. + customer_id (str): + Required. ID of the customer whose ad + group ad labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAdLabelOperation]): + Required. The list of operations to + perform on ad group ad labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupAdLabelsResponse: + Response message for an ad group ad + labels mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_ad_label_service.MutateAdGroupAdLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_ad_label_service.MutateAdGroupAdLabelsRequest + ): + request = ad_group_ad_label_service.MutateAdGroupAdLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_ad_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupAdLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/__init__.py new file mode 100644 index 000000000..eb86e88ee --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupAdLabelServiceTransport +from .grpc import AdGroupAdLabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupAdLabelServiceTransport]] +_transport_registry["grpc"] = AdGroupAdLabelServiceGrpcTransport + +__all__ = ( + "AdGroupAdLabelServiceTransport", + "AdGroupAdLabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/base.py new file mode 100644 index 000000000..5be46f29c --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_label_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupAdLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAdLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_ad_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_ad_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_ad_labels( + self, + ) -> Callable[ + [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], + Union[ + ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, + Awaitable[ad_group_ad_label_service.MutateAdGroupAdLabelsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupAdLabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/grpc.py new file mode 100644 index 000000000..dfc791924 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_label_service/transports/grpc.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_label_service +from .base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupAdLabelServiceGrpcTransport(AdGroupAdLabelServiceTransport): + """gRPC backend transport for AdGroupAdLabelService. + + Service to manage labels on ad group ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_ad_labels( + self, + ) -> Callable[ + [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], + ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, + ]: + r"""Return a callable for the mutate ad group ad labels method over gRPC. + + Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdLabelsRequest], + ~.MutateAdGroupAdLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ad_labels" not in self._stubs: + self._stubs[ + "mutate_ad_group_ad_labels" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupAdLabelService/MutateAdGroupAdLabels", + request_serializer=ad_group_ad_label_service.MutateAdGroupAdLabelsRequest.serialize, + response_deserializer=ad_group_ad_label_service.MutateAdGroupAdLabelsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_ad_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupAdLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_ad_service/__init__.py new file mode 100644 index 000000000..55aa7ee02 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupAdServiceClient + +__all__ = ("AdGroupAdServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_service/client.py b/google/ads/googleads/v12/services/services/ad_group_ad_service/client.py new file mode 100644 index 000000000..f58deb466 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_service/client.py @@ -0,0 +1,553 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAdServiceGrpcTransport + + +class AdGroupAdServiceClientMeta(type): + """Metaclass for the AdGroupAdService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAdServiceTransport]] + _transport_registry["grpc"] = AdGroupAdServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupAdServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAdServiceClient(metaclass=AdGroupAdServiceClientMeta): + """Service to manage ads in an ad group.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_path(customer_id: str, ad_id: str,) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, ad_group_id: str, ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, ad_group_id: str, ad_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupAdServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupAdServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupAdServiceTransport): + # transport is a AdGroupAdServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_ads( + self, + request: Union[ + ad_group_ad_service.MutateAdGroupAdsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ad_group_ad_service.AdGroupAdOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_ad_service.MutateAdGroupAdsResponse: + r"""Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupAdsRequest, dict]): + The request object. Request message for + [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v12.services.AdGroupAdService.MutateAdGroupAds]. + customer_id (str): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAdOperation]): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupAdsResponse: + Response message for an ad group ad + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_ad_service.MutateAdGroupAdsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, ad_group_ad_service.MutateAdGroupAdsRequest): + request = ad_group_ad_service.MutateAdGroupAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupAdServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/__init__.py new file mode 100644 index 000000000..803932fa7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupAdServiceTransport +from .grpc import AdGroupAdServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupAdServiceTransport]] +_transport_registry["grpc"] = AdGroupAdServiceGrpcTransport + +__all__ = ( + "AdGroupAdServiceTransport", + "AdGroupAdServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/base.py new file mode 100644 index 000000000..2061d2eed --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupAdServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAdService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_ads: gapic_v1.method.wrap_method( + self.mutate_ad_group_ads, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_ads( + self, + ) -> Callable[ + [ad_group_ad_service.MutateAdGroupAdsRequest], + Union[ + ad_group_ad_service.MutateAdGroupAdsResponse, + Awaitable[ad_group_ad_service.MutateAdGroupAdsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupAdServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/grpc.py new file mode 100644 index 000000000..874b096d5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_ad_service/transports/grpc.py @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_ad_service +from .base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupAdServiceGrpcTransport(AdGroupAdServiceTransport): + """gRPC backend transport for AdGroupAdService. + + Service to manage ads in an ad group. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_ads( + self, + ) -> Callable[ + [ad_group_ad_service.MutateAdGroupAdsRequest], + ad_group_ad_service.MutateAdGroupAdsResponse, + ]: + r"""Return a callable for the mutate ad group ads method over gRPC. + + Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdsRequest], + ~.MutateAdGroupAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ads" not in self._stubs: + self._stubs["mutate_ad_group_ads"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupAdService/MutateAdGroupAds", + request_serializer=ad_group_ad_service.MutateAdGroupAdsRequest.serialize, + response_deserializer=ad_group_ad_service.MutateAdGroupAdsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_ads"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupAdServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_asset_service/__init__.py new file mode 100644 index 000000000..fd44e9775 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupAssetServiceClient + +__all__ = ("AdGroupAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_service/client.py b/google/ads/googleads/v12/services/services/ad_group_asset_service/client.py new file mode 100644 index 000000000..dc77adf3c --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_service/client.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAssetServiceGrpcTransport + + +class AdGroupAssetServiceClientMeta(type): + """Metaclass for the AdGroupAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAssetServiceTransport]] + _transport_registry["grpc"] = AdGroupAssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAssetServiceClient(metaclass=AdGroupAssetServiceClientMeta): + """Service to manage ad group assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, ad_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupAssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupAssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupAssetServiceTransport): + # transport is a AdGroupAssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_assets( + self, + request: Union[ + ad_group_asset_service.MutateAdGroupAssetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_asset_service.AdGroupAssetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_asset_service.MutateAdGroupAssetsResponse: + r"""Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupAssetsRequest, dict]): + The request object. Request message for + [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v12.services.AdGroupAssetService.MutateAdGroupAssets]. + customer_id (str): + Required. The ID of the customer + whose ad group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAssetOperation]): + Required. The list of operations to + perform on individual ad group assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupAssetsResponse: + Response message for an ad group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_asset_service.MutateAdGroupAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_asset_service.MutateAdGroupAssetsRequest + ): + request = ad_group_asset_service.MutateAdGroupAssetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/__init__.py new file mode 100644 index 000000000..454c76cb9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupAssetServiceTransport +from .grpc import AdGroupAssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupAssetServiceTransport]] +_transport_registry["grpc"] = AdGroupAssetServiceGrpcTransport + +__all__ = ( + "AdGroupAssetServiceTransport", + "AdGroupAssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/base.py new file mode 100644 index 000000000..1c333f1fa --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupAssetServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_assets: gapic_v1.method.wrap_method( + self.mutate_ad_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_assets( + self, + ) -> Callable[ + [ad_group_asset_service.MutateAdGroupAssetsRequest], + Union[ + ad_group_asset_service.MutateAdGroupAssetsResponse, + Awaitable[ad_group_asset_service.MutateAdGroupAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/grpc.py new file mode 100644 index 000000000..c9a9ebb67 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_service/transports/grpc.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_service +from .base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupAssetServiceGrpcTransport(AdGroupAssetServiceTransport): + """gRPC backend transport for AdGroupAssetService. + + Service to manage ad group assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_assets( + self, + ) -> Callable[ + [ad_group_asset_service.MutateAdGroupAssetsRequest], + ad_group_asset_service.MutateAdGroupAssetsResponse, + ]: + r"""Return a callable for the mutate ad group assets method over gRPC. + + Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAssetsRequest], + ~.MutateAdGroupAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_assets" not in self._stubs: + self._stubs[ + "mutate_ad_group_assets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupAssetService/MutateAdGroupAssets", + request_serializer=ad_group_asset_service.MutateAdGroupAssetsRequest.serialize, + response_deserializer=ad_group_asset_service.MutateAdGroupAssetsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_set_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/__init__.py new file mode 100644 index 000000000..55a5ebc43 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupAssetSetServiceClient + +__all__ = ("AdGroupAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_set_service/client.py b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/client.py new file mode 100644 index 000000000..197b63eda --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/client.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupAssetSetServiceGrpcTransport + + +class AdGroupAssetSetServiceClientMeta(type): + """Metaclass for the AdGroupAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAssetSetServiceTransport]] + _transport_registry["grpc"] = AdGroupAssetSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAssetSetServiceClient(metaclass=AdGroupAssetSetServiceClientMeta): + """Service to manage ad group asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_set_path( + customer_id: str, ad_group_id: str, asset_set_id: str, + ) -> str: + """Returns a fully-qualified ad_group_asset_set string.""" + return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupAssetSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupAssetSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupAssetSetServiceTransport): + # transport is a AdGroupAssetSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_asset_sets( + self, + request: Union[ + ad_group_asset_set_service.MutateAdGroupAssetSetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_asset_set_service.AdGroupAssetSetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_asset_set_service.MutateAdGroupAssetSetsResponse: + r"""Creates, or removes ad group asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupAssetSetsRequest, dict]): + The request object. Request message for + [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v12.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. + customer_id (str): + Required. The ID of the customer + whose ad group asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAssetSetOperation]): + Required. The list of operations to + perform on individual ad group asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupAssetSetsResponse: + Response message for an ad group + asset set mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_asset_set_service.MutateAdGroupAssetSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_asset_set_service.MutateAdGroupAssetSetsRequest + ): + request = ad_group_asset_set_service.MutateAdGroupAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/__init__.py new file mode 100644 index 000000000..1d0abeaf0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupAssetSetServiceTransport +from .grpc import AdGroupAssetSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupAssetSetServiceTransport]] +_transport_registry["grpc"] = AdGroupAssetSetServiceGrpcTransport + +__all__ = ( + "AdGroupAssetSetServiceTransport", + "AdGroupAssetSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/base.py new file mode 100644 index 000000000..01b4be92b --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupAssetSetServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_asset_sets: gapic_v1.method.wrap_method( + self.mutate_ad_group_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_asset_sets( + self, + ) -> Callable[ + [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], + Union[ + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, + Awaitable[ + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupAssetSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..230b06326 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_asset_set_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_asset_set_service +from .base import AdGroupAssetSetServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupAssetSetServiceGrpcTransport(AdGroupAssetSetServiceTransport): + """gRPC backend transport for AdGroupAssetSetService. + + Service to manage ad group asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_asset_sets( + self, + ) -> Callable[ + [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, + ]: + r"""Return a callable for the mutate ad group asset sets method over gRPC. + + Creates, or removes ad group asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAdGroupAssetSetsRequest], + ~.MutateAdGroupAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_asset_sets" not in self._stubs: + self._stubs[ + "mutate_ad_group_asset_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupAssetSetService/MutateAdGroupAssetSets", + request_serializer=ad_group_asset_set_service.MutateAdGroupAssetSetsRequest.serialize, + response_deserializer=ad_group_asset_set_service.MutateAdGroupAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_asset_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/__init__.py new file mode 100644 index 000000000..96416cbda --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupBidModifierServiceClient + +__all__ = ("AdGroupBidModifierServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/client.py b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/client.py new file mode 100644 index 000000000..c07579630 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/client.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupBidModifierServiceGrpcTransport + + +class AdGroupBidModifierServiceClientMeta(type): + """Metaclass for the AdGroupBidModifierService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupBidModifierServiceTransport]] + _transport_registry["grpc"] = AdGroupBidModifierServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupBidModifierServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupBidModifierServiceClient( + metaclass=AdGroupBidModifierServiceClientMeta +): + """Service to manage ad group bid modifiers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupBidModifierServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupBidModifierServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group bid modifier service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupBidModifierServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupBidModifierServiceTransport): + # transport is a AdGroupBidModifierServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_bid_modifiers( + self, + request: Union[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_bid_modifier_service.AdGroupBidModifierOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse: + r"""Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupBidModifiersRequest, dict]): + The request object. Request message for + [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v12.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. + customer_id (str): + Required. ID of the customer whose ad + group bid modifiers are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupBidModifierOperation]): + Required. The list of operations to + perform on individual ad group bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupBidModifiersResponse: + Response message for ad group bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, + ): + request = ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupBidModifierServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/__init__.py new file mode 100644 index 000000000..c291e4970 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupBidModifierServiceTransport +from .grpc import AdGroupBidModifierServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupBidModifierServiceTransport]] +_transport_registry["grpc"] = AdGroupBidModifierServiceGrpcTransport + +__all__ = ( + "AdGroupBidModifierServiceTransport", + "AdGroupBidModifierServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/base.py new file mode 100644 index 000000000..1c4490f5a --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_bid_modifier_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupBidModifierServiceTransport(abc.ABC): + """Abstract transport class for AdGroupBidModifierService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_bid_modifiers: gapic_v1.method.wrap_method( + self.mutate_ad_group_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_bid_modifiers( + self, + ) -> Callable[ + [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], + Union[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, + Awaitable[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupBidModifierServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/grpc.py new file mode 100644 index 000000000..401e7a087 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_bid_modifier_service/transports/grpc.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_bid_modifier_service, +) +from .base import AdGroupBidModifierServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupBidModifierServiceGrpcTransport( + AdGroupBidModifierServiceTransport +): + """gRPC backend transport for AdGroupBidModifierService. + + Service to manage ad group bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_bid_modifiers( + self, + ) -> Callable[ + [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, + ]: + r"""Return a callable for the mutate ad group bid modifiers method over gRPC. + + Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAdGroupBidModifiersRequest], + ~.MutateAdGroupBidModifiersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_bid_modifiers" not in self._stubs: + self._stubs[ + "mutate_ad_group_bid_modifiers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupBidModifierService/MutateAdGroupBidModifiers", + request_serializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest.serialize, + response_deserializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse.deserialize, + ) + return self._stubs["mutate_ad_group_bid_modifiers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/__init__.py new file mode 100644 index 000000000..096b3647b --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupCriterionCustomizerServiceClient + +__all__ = ("AdGroupCriterionCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/client.py b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/client.py new file mode 100644 index 000000000..89da8b470 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/client.py @@ -0,0 +1,545 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_customizer_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionCustomizerServiceGrpcTransport + + +class AdGroupCriterionCustomizerServiceClientMeta(type): + """Metaclass for the AdGroupCriterionCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionCustomizerServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionCustomizerServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupCriterionCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionCustomizerServiceClient( + metaclass=AdGroupCriterionCustomizerServiceClientMeta +): + """Service to manage ad group criterion customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, AdGroupCriterionCustomizerServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupCriterionCustomizerServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupCriterionCustomizerServiceTransport): + # transport is a AdGroupCriterionCustomizerServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_criterion_customizers( + self, + request: Union[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse: + r"""Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupCriterionCustomizersRequest, dict]): + The request object. Request message for + [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v12.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. + customer_id (str): + Required. The ID of the customer + whose ad group criterion customizers are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionCustomizerOperation]): + Required. The list of operations to + perform on individual ad group criterion + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupCriterionCustomizersResponse: + Response message for an ad group + criterion customizer mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + ): + request = ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criterion_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupCriterionCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/__init__.py new file mode 100644 index 000000000..bf72a7e01 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupCriterionCustomizerServiceTransport +from .grpc import AdGroupCriterionCustomizerServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupCriterionCustomizerServiceTransport]] +_transport_registry["grpc"] = AdGroupCriterionCustomizerServiceGrpcTransport + +__all__ = ( + "AdGroupCriterionCustomizerServiceTransport", + "AdGroupCriterionCustomizerServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/base.py new file mode 100644 index 000000000..a93d71893 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_customizer_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupCriterionCustomizerServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criterion_customizers: gapic_v1.method.wrap_method( + self.mutate_ad_group_criterion_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criterion_customizers( + self, + ) -> Callable[ + [ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest + ], + Union[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, + Awaitable[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionCustomizerServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/grpc.py new file mode 100644 index 000000000..f1e96af4a --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_customizer_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_customizer_service, +) +from .base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class AdGroupCriterionCustomizerServiceGrpcTransport( + AdGroupCriterionCustomizerServiceTransport +): + """gRPC backend transport for AdGroupCriterionCustomizerService. + + Service to manage ad group criterion customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_criterion_customizers( + self, + ) -> Callable[ + [ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest + ], + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, + ]: + r"""Return a callable for the mutate ad group criterion + customizers method over gRPC. + + Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCriterionCustomizersRequest], + ~.MutateAdGroupCriterionCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_customizers" not in self._stubs: + self._stubs[ + "mutate_ad_group_criterion_customizers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupCriterionCustomizerService/MutateAdGroupCriterionCustomizers", + request_serializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest.serialize, + response_deserializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse.deserialize, + ) + return self._stubs["mutate_ad_group_criterion_customizers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupCriterionCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/__init__.py new file mode 100644 index 000000000..c1add723c --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupCriterionLabelServiceClient + +__all__ = ("AdGroupCriterionLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/client.py b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/client.py new file mode 100644 index 000000000..a59f64213 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/client.py @@ -0,0 +1,542 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_label_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionLabelServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionLabelServiceGrpcTransport + + +class AdGroupCriterionLabelServiceClientMeta(type): + """Metaclass for the AdGroupCriterionLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionLabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupCriterionLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionLabelServiceClient( + metaclass=AdGroupCriterionLabelServiceClientMeta +): + """Service to manage labels on ad group criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, ad_group_id: str, criterion_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, AdGroupCriterionLabelServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupCriterionLabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupCriterionLabelServiceTransport): + # transport is a AdGroupCriterionLabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_criterion_labels( + self, + request: Union[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_criterion_label_service.AdGroupCriterionLabelOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse: + r"""Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupCriterionLabelsRequest, dict]): + The request object. Request message for + [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v12.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. + customer_id (str): + Required. ID of the customer whose ad + group criterion labels are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionLabelOperation]): + Required. The list of operations to + perform on ad group criterion labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupCriterionLabelsResponse: + Response message for an ad group + criterion labels mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + ): + request = ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criterion_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupCriterionLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/__init__.py new file mode 100644 index 000000000..37d2aa06d --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupCriterionLabelServiceTransport +from .grpc import AdGroupCriterionLabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupCriterionLabelServiceTransport]] +_transport_registry["grpc"] = AdGroupCriterionLabelServiceGrpcTransport + +__all__ = ( + "AdGroupCriterionLabelServiceTransport", + "AdGroupCriterionLabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/base.py new file mode 100644 index 000000000..3c74a50a2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_label_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupCriterionLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criterion_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_criterion_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criterion_labels( + self, + ) -> Callable[ + [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], + Union[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, + Awaitable[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionLabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/grpc.py new file mode 100644 index 000000000..89cbb4353 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_label_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_label_service, +) +from .base import AdGroupCriterionLabelServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupCriterionLabelServiceGrpcTransport( + AdGroupCriterionLabelServiceTransport +): + """gRPC backend transport for AdGroupCriterionLabelService. + + Service to manage labels on ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_criterion_labels( + self, + ) -> Callable[ + [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, + ]: + r"""Return a callable for the mutate ad group criterion + labels method over gRPC. + + Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriterionLabelsRequest], + ~.MutateAdGroupCriterionLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_labels" not in self._stubs: + self._stubs[ + "mutate_ad_group_criterion_labels" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupCriterionLabelService/MutateAdGroupCriterionLabels", + request_serializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest.serialize, + response_deserializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_criterion_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupCriterionLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_service/__init__.py new file mode 100644 index 000000000..dae8637e6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupCriterionServiceClient + +__all__ = ("AdGroupCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_service/client.py b/google/ads/googleads/v12/services/services/ad_group_criterion_service/client.py new file mode 100644 index 000000000..92915c713 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_service/client.py @@ -0,0 +1,547 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionServiceGrpcTransport + + +class AdGroupCriterionServiceClientMeta(type): + """Metaclass for the AdGroupCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionServiceClient( + metaclass=AdGroupCriterionServiceClientMeta +): + """Service to manage ad group criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, ad_group_id: str, criterion_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupCriterionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupCriterionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupCriterionServiceTransport): + # transport is a AdGroupCriterionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_criteria( + self, + request: Union[ + ad_group_criterion_service.MutateAdGroupCriteriaRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_criterion_service.AdGroupCriterionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_criterion_service.MutateAdGroupCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupCriteriaRequest, dict]): + The request object. Request message for + [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v12.services.AdGroupCriterionService.MutateAdGroupCriteria]. + customer_id (str): + Required. ID of the customer whose + criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupCriteriaResponse: + Response message for an ad group + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_criterion_service.MutateAdGroupCriteriaRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_criterion_service.MutateAdGroupCriteriaRequest + ): + request = ad_group_criterion_service.MutateAdGroupCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/__init__.py new file mode 100644 index 000000000..77c113abd --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupCriterionServiceTransport +from .grpc import AdGroupCriterionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupCriterionServiceTransport]] +_transport_registry["grpc"] = AdGroupCriterionServiceGrpcTransport + +__all__ = ( + "AdGroupCriterionServiceTransport", + "AdGroupCriterionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/base.py new file mode 100644 index 000000000..2a6add57b --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_criterion_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupCriterionServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criteria: gapic_v1.method.wrap_method( + self.mutate_ad_group_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criteria( + self, + ) -> Callable[ + [ad_group_criterion_service.MutateAdGroupCriteriaRequest], + Union[ + ad_group_criterion_service.MutateAdGroupCriteriaResponse, + Awaitable[ad_group_criterion_service.MutateAdGroupCriteriaResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/grpc.py new file mode 100644 index 000000000..9e06ac04c --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_criterion_service/transports/grpc.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_criterion_service +from .base import AdGroupCriterionServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupCriterionServiceGrpcTransport(AdGroupCriterionServiceTransport): + """gRPC backend transport for AdGroupCriterionService. + + Service to manage ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_criteria( + self, + ) -> Callable[ + [ad_group_criterion_service.MutateAdGroupCriteriaRequest], + ad_group_criterion_service.MutateAdGroupCriteriaResponse, + ]: + r"""Return a callable for the mutate ad group criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriteriaRequest], + ~.MutateAdGroupCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criteria" not in self._stubs: + self._stubs[ + "mutate_ad_group_criteria" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupCriterionService/MutateAdGroupCriteria", + request_serializer=ad_group_criterion_service.MutateAdGroupCriteriaRequest.serialize, + response_deserializer=ad_group_criterion_service.MutateAdGroupCriteriaResponse.deserialize, + ) + return self._stubs["mutate_ad_group_criteria"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_customizer_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_customizer_service/__init__.py new file mode 100644 index 000000000..92ff6d237 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_customizer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupCustomizerServiceClient + +__all__ = ("AdGroupCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_customizer_service/client.py b/google/ads/googleads/v12/services/services/ad_group_customizer_service/client.py new file mode 100644 index 000000000..0d2392ffd --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_customizer_service/client.py @@ -0,0 +1,531 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCustomizerServiceGrpcTransport + + +class AdGroupCustomizerServiceClientMeta(type): + """Metaclass for the AdGroupCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCustomizerServiceTransport]] + _transport_registry["grpc"] = AdGroupCustomizerServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCustomizerServiceClient( + metaclass=AdGroupCustomizerServiceClientMeta +): + """Service to manage ad group customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, ad_group_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupCustomizerServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupCustomizerServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupCustomizerServiceTransport): + # transport is a AdGroupCustomizerServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_customizers( + self, + request: Union[ + ad_group_customizer_service.MutateAdGroupCustomizersRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_customizer_service.AdGroupCustomizerOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_customizer_service.MutateAdGroupCustomizersResponse: + r"""Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupCustomizersRequest, dict]): + The request object. Request message for + [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v12.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. + customer_id (str): + Required. The ID of the customer + whose ad group customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCustomizerOperation]): + Required. The list of operations to + perform on individual ad group + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupCustomizersResponse: + Response message for an ad group + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_customizer_service.MutateAdGroupCustomizersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_customizer_service.MutateAdGroupCustomizersRequest + ): + request = ad_group_customizer_service.MutateAdGroupCustomizersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/__init__.py new file mode 100644 index 000000000..e94c27927 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupCustomizerServiceTransport +from .grpc import AdGroupCustomizerServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupCustomizerServiceTransport]] +_transport_registry["grpc"] = AdGroupCustomizerServiceGrpcTransport + +__all__ = ( + "AdGroupCustomizerServiceTransport", + "AdGroupCustomizerServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/base.py new file mode 100644 index 000000000..cef762c0f --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_customizer_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupCustomizerServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_customizers: gapic_v1.method.wrap_method( + self.mutate_ad_group_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_customizers( + self, + ) -> Callable[ + [ad_group_customizer_service.MutateAdGroupCustomizersRequest], + Union[ + ad_group_customizer_service.MutateAdGroupCustomizersResponse, + Awaitable[ + ad_group_customizer_service.MutateAdGroupCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupCustomizerServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/grpc.py new file mode 100644 index 000000000..175bb5fda --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_customizer_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_customizer_service +from .base import AdGroupCustomizerServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupCustomizerServiceGrpcTransport(AdGroupCustomizerServiceTransport): + """gRPC backend transport for AdGroupCustomizerService. + + Service to manage ad group customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_customizers( + self, + ) -> Callable[ + [ad_group_customizer_service.MutateAdGroupCustomizersRequest], + ad_group_customizer_service.MutateAdGroupCustomizersResponse, + ]: + r"""Return a callable for the mutate ad group customizers method over gRPC. + + Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCustomizersRequest], + ~.MutateAdGroupCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_customizers" not in self._stubs: + self._stubs[ + "mutate_ad_group_customizers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupCustomizerService/MutateAdGroupCustomizers", + request_serializer=ad_group_customizer_service.MutateAdGroupCustomizersRequest.serialize, + response_deserializer=ad_group_customizer_service.MutateAdGroupCustomizersResponse.deserialize, + ) + return self._stubs["mutate_ad_group_customizers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/__init__.py new file mode 100644 index 000000000..98389130e --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupExtensionSettingServiceClient + +__all__ = ("AdGroupExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/client.py b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/client.py new file mode 100644 index 000000000..0fab4ec0c --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/client.py @@ -0,0 +1,548 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_extension_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupExtensionSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupExtensionSettingServiceGrpcTransport + + +class AdGroupExtensionSettingServiceClientMeta(type): + """Metaclass for the AdGroupExtensionSettingService 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[AdGroupExtensionSettingServiceTransport]] + _transport_registry["grpc"] = AdGroupExtensionSettingServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupExtensionSettingServiceTransport]: + """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 AdGroupExtensionSettingServiceClient( + metaclass=AdGroupExtensionSettingServiceClientMeta +): + """Service to manage ad group extension settings.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupExtensionSettingServiceClient: 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: + AdGroupExtensionSettingServiceClient: 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) -> AdGroupExtensionSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupExtensionSettingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_extension_setting_path( + customer_id: str, ad_group_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified ad_group_extension_setting string.""" + return "customers/{customer_id}/adGroupExtensionSettings/{ad_group_id}~{extension_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_ad_group_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a ad_group_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, AdGroupExtensionSettingServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group extension setting service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupExtensionSettingServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupExtensionSettingServiceTransport): + # transport is a AdGroupExtensionSettingServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_extension_settings( + self, + request: Union[ + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_extension_setting_service.AdGroupExtensionSettingOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_extension_setting_service.MutateAdGroupExtensionSettingsResponse: + r"""Creates, updates, or removes ad group extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupExtensionSettingsRequest, dict]): + The request object. Request message for + [AdGroupExtensionSettingService.MutateAdGroupExtensionSettings][google.ads.googleads.v12.services.AdGroupExtensionSettingService.MutateAdGroupExtensionSettings]. + customer_id (str): + Required. The ID of the customer + whose ad group extension settings are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupExtensionSettingOperation]): + Required. The list of operations to + perform on individual ad group extension + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupExtensionSettingsResponse: + Response message for an ad group + extension setting mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest, + ): + request = ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_extension_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/__init__.py new file mode 100644 index 000000000..3ba086f97 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupExtensionSettingServiceTransport +from .grpc import AdGroupExtensionSettingServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupExtensionSettingServiceTransport]] +_transport_registry["grpc"] = AdGroupExtensionSettingServiceGrpcTransport + +__all__ = ( + "AdGroupExtensionSettingServiceTransport", + "AdGroupExtensionSettingServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/base.py new file mode 100644 index 000000000..539204585 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_extension_setting_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupExtensionSettingServiceTransport(abc.ABC): + """Abstract transport class for AdGroupExtensionSettingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_extension_settings: gapic_v1.method.wrap_method( + self.mutate_ad_group_extension_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_extension_settings( + self, + ) -> Callable[ + [ + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest + ], + Union[ + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsResponse, + Awaitable[ + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupExtensionSettingServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/grpc.py new file mode 100644 index 000000000..6033d5001 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_extension_setting_service/transports/grpc.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + ad_group_extension_setting_service, +) +from .base import AdGroupExtensionSettingServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupExtensionSettingServiceGrpcTransport( + AdGroupExtensionSettingServiceTransport +): + """gRPC backend transport for AdGroupExtensionSettingService. + + Service to manage ad group extension settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_extension_settings( + self, + ) -> Callable[ + [ + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest + ], + ad_group_extension_setting_service.MutateAdGroupExtensionSettingsResponse, + ]: + r"""Return a callable for the mutate ad group extension + settings method over gRPC. + + Creates, updates, or removes ad group extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupExtensionSettingsRequest], + ~.MutateAdGroupExtensionSettingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_extension_settings" not in self._stubs: + self._stubs[ + "mutate_ad_group_extension_settings" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupExtensionSettingService/MutateAdGroupExtensionSettings", + request_serializer=ad_group_extension_setting_service.MutateAdGroupExtensionSettingsRequest.serialize, + response_deserializer=ad_group_extension_setting_service.MutateAdGroupExtensionSettingsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_extension_settings"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupExtensionSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_feed_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_feed_service/__init__.py new file mode 100644 index 000000000..ecfbd0029 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_feed_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupFeedServiceClient + +__all__ = ("AdGroupFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_feed_service/client.py b/google/ads/googleads/v12/services/services/ad_group_feed_service/client.py new file mode 100644 index 000000000..cc9eca6c7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_feed_service/client.py @@ -0,0 +1,524 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_feed_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupFeedServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupFeedServiceGrpcTransport + + +class AdGroupFeedServiceClientMeta(type): + """Metaclass for the AdGroupFeedService 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[AdGroupFeedServiceTransport]] + _transport_registry["grpc"] = AdGroupFeedServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupFeedServiceTransport]: + """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 AdGroupFeedServiceClient(metaclass=AdGroupFeedServiceClientMeta): + """Service to manage ad group feeds.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupFeedServiceClient: 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: + AdGroupFeedServiceClient: 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) -> AdGroupFeedServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupFeedServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_feed_path( + customer_id: str, ad_group_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified ad_group_feed string.""" + return "customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, feed_id=feed_id, + ) + + @staticmethod + def parse_ad_group_feed_path(path: str) -> Dict[str, str]: + """Parses a ad_group_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupFeedServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group feed 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 (Union[str, AdGroupFeedServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupFeedServiceTransport): + # transport is a AdGroupFeedServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_feeds( + self, + request: Union[ + ad_group_feed_service.MutateAdGroupFeedsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ad_group_feed_service.AdGroupFeedOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_feed_service.MutateAdGroupFeedsResponse: + r"""Creates, updates, or removes ad group feeds. Operation statuses + are returned. + + List of thrown errors: `AdGroupFeedError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupFeedsRequest, dict]): + The request object. Request message for + [AdGroupFeedService.MutateAdGroupFeeds][google.ads.googleads.v12.services.AdGroupFeedService.MutateAdGroupFeeds]. + customer_id (str): + Required. The ID of the customer + whose ad group feeds are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupFeedOperation]): + Required. The list of operations to + perform on individual ad group feeds. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupFeedsResponse: + Response message for an ad group feed + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_feed_service.MutateAdGroupFeedsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_feed_service.MutateAdGroupFeedsRequest + ): + request = ad_group_feed_service.MutateAdGroupFeedsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_feeds + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/__init__.py new file mode 100644 index 000000000..64c45cecf --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupFeedServiceTransport +from .grpc import AdGroupFeedServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupFeedServiceTransport]] +_transport_registry["grpc"] = AdGroupFeedServiceGrpcTransport + +__all__ = ( + "AdGroupFeedServiceTransport", + "AdGroupFeedServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/base.py new file mode 100644 index 000000000..b288084d1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_feed_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupFeedServiceTransport(abc.ABC): + """Abstract transport class for AdGroupFeedService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_feeds: gapic_v1.method.wrap_method( + self.mutate_ad_group_feeds, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_feeds( + self, + ) -> Callable[ + [ad_group_feed_service.MutateAdGroupFeedsRequest], + Union[ + ad_group_feed_service.MutateAdGroupFeedsResponse, + Awaitable[ad_group_feed_service.MutateAdGroupFeedsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupFeedServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/grpc.py new file mode 100644 index 000000000..4e30aabb7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_feed_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_feed_service +from .base import AdGroupFeedServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupFeedServiceGrpcTransport(AdGroupFeedServiceTransport): + """gRPC backend transport for AdGroupFeedService. + + Service to manage ad group feeds. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_feeds( + self, + ) -> Callable[ + [ad_group_feed_service.MutateAdGroupFeedsRequest], + ad_group_feed_service.MutateAdGroupFeedsResponse, + ]: + r"""Return a callable for the mutate ad group feeds method over gRPC. + + Creates, updates, or removes ad group feeds. Operation statuses + are returned. + + List of thrown errors: `AdGroupFeedError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAdGroupFeedsRequest], + ~.MutateAdGroupFeedsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_feeds" not in self._stubs: + self._stubs[ + "mutate_ad_group_feeds" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupFeedService/MutateAdGroupFeeds", + request_serializer=ad_group_feed_service.MutateAdGroupFeedsRequest.serialize, + response_deserializer=ad_group_feed_service.MutateAdGroupFeedsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_feeds"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupFeedServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_label_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_label_service/__init__.py new file mode 100644 index 000000000..c790d9e7f --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupLabelServiceClient + +__all__ = ("AdGroupLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_label_service/client.py b/google/ads/googleads/v12/services/services/ad_group_label_service/client.py new file mode 100644 index 000000000..e263cb492 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_label_service/client.py @@ -0,0 +1,522 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupLabelServiceGrpcTransport + + +class AdGroupLabelServiceClientMeta(type): + """Metaclass for the AdGroupLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupLabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupLabelServiceClient(metaclass=AdGroupLabelServiceClientMeta): + """Service to manage labels on ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, ad_group_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupLabelServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupLabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupLabelServiceTransport): + # transport is a AdGroupLabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_group_labels( + self, + request: Union[ + ad_group_label_service.MutateAdGroupLabelsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + ad_group_label_service.AdGroupLabelOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_label_service.MutateAdGroupLabelsResponse: + r"""Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupLabelsRequest, dict]): + The request object. Request message for + [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v12.services.AdGroupLabelService.MutateAdGroupLabels]. + customer_id (str): + Required. ID of the customer whose ad + group labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupLabelOperation]): + Required. The list of operations to + perform on ad group labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupLabelsResponse: + Response message for an ad group + labels mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_label_service.MutateAdGroupLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_group_label_service.MutateAdGroupLabelsRequest + ): + request = ad_group_label_service.MutateAdGroupLabelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/__init__.py new file mode 100644 index 000000000..aa35b060f --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupLabelServiceTransport +from .grpc import AdGroupLabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupLabelServiceTransport]] +_transport_registry["grpc"] = AdGroupLabelServiceGrpcTransport + +__all__ = ( + "AdGroupLabelServiceTransport", + "AdGroupLabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_label_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/base.py new file mode 100644 index 000000000..6844041e5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_label_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_labels( + self, + ) -> Callable[ + [ad_group_label_service.MutateAdGroupLabelsRequest], + Union[ + ad_group_label_service.MutateAdGroupLabelsResponse, + Awaitable[ad_group_label_service.MutateAdGroupLabelsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupLabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/grpc.py new file mode 100644 index 000000000..a5f6536e3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_label_service/transports/grpc.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_label_service +from .base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupLabelServiceGrpcTransport(AdGroupLabelServiceTransport): + """gRPC backend transport for AdGroupLabelService. + + Service to manage labels on ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_group_labels( + self, + ) -> Callable[ + [ad_group_label_service.MutateAdGroupLabelsRequest], + ad_group_label_service.MutateAdGroupLabelsResponse, + ]: + r"""Return a callable for the mutate ad group labels method over gRPC. + + Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupLabelsRequest], + ~.MutateAdGroupLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_labels" not in self._stubs: + self._stubs[ + "mutate_ad_group_labels" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupLabelService/MutateAdGroupLabels", + request_serializer=ad_group_label_service.MutateAdGroupLabelsRequest.serialize, + response_deserializer=ad_group_label_service.MutateAdGroupLabelsResponse.deserialize, + ) + return self._stubs["mutate_ad_group_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_service/__init__.py b/google/ads/googleads/v12/services/services/ad_group_service/__init__.py new file mode 100644 index 000000000..ae3a0b219 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdGroupServiceClient + +__all__ = ("AdGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_service/client.py b/google/ads/googleads/v12/services/services/ad_group_service/client.py new file mode 100644 index 000000000..f28f9a7a9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_service/client.py @@ -0,0 +1,524 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupServiceGrpcTransport + + +class AdGroupServiceClientMeta(type): + """Metaclass for the AdGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupServiceTransport]] + _transport_registry["grpc"] = AdGroupServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupServiceClient(metaclass=AdGroupServiceClientMeta): + """Service to manage ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, ad_group_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdGroupServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdGroupServiceTransport): + # transport is a AdGroupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_groups( + self, + request: Union[ad_group_service.MutateAdGroupsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[ad_group_service.AdGroupOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_group_service.MutateAdGroupsResponse: + r"""Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdGroupsRequest, dict]): + The request object. Request message for + [AdGroupService.MutateAdGroups][google.ads.googleads.v12.services.AdGroupService.MutateAdGroups]. + customer_id (str): + Required. The ID of the customer + whose ad groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupOperation]): + Required. The list of operations to + perform on individual ad groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdGroupsResponse: + Response message for an ad group + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_group_service.MutateAdGroupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, ad_group_service.MutateAdGroupsRequest): + request = ad_group_service.MutateAdGroupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_ad_groups] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_group_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_group_service/transports/__init__.py new file mode 100644 index 000000000..2fd5ba12d --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdGroupServiceTransport +from .grpc import AdGroupServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdGroupServiceTransport]] +_transport_registry["grpc"] = AdGroupServiceGrpcTransport + +__all__ = ( + "AdGroupServiceTransport", + "AdGroupServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_group_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_group_service/transports/base.py new file mode 100644 index 000000000..fdabdbef0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdGroupServiceTransport(abc.ABC): + """Abstract transport class for AdGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_groups: gapic_v1.method.wrap_method( + self.mutate_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_groups( + self, + ) -> Callable[ + [ad_group_service.MutateAdGroupsRequest], + Union[ + ad_group_service.MutateAdGroupsResponse, + Awaitable[ad_group_service.MutateAdGroupsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdGroupServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_group_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_group_service/transports/grpc.py new file mode 100644 index 000000000..2665ce8da --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_group_service/transports/grpc.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_group_service +from .base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO + + +class AdGroupServiceGrpcTransport(AdGroupServiceTransport): + """gRPC backend transport for AdGroupService. + + Service to manage ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_groups( + self, + ) -> Callable[ + [ad_group_service.MutateAdGroupsRequest], + ad_group_service.MutateAdGroupsResponse, + ]: + r"""Return a callable for the mutate ad groups method over gRPC. + + Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupsRequest], + ~.MutateAdGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_groups" not in self._stubs: + self._stubs["mutate_ad_groups"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdGroupService/MutateAdGroups", + request_serializer=ad_group_service.MutateAdGroupsRequest.serialize, + response_deserializer=ad_group_service.MutateAdGroupsResponse.deserialize, + ) + return self._stubs["mutate_ad_groups"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_parameter_service/__init__.py b/google/ads/googleads/v12/services/services/ad_parameter_service/__init__.py new file mode 100644 index 000000000..1d0f08d29 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_parameter_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdParameterServiceClient + +__all__ = ("AdParameterServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_parameter_service/client.py b/google/ads/googleads/v12/services/services/ad_parameter_service/client.py new file mode 100644 index 000000000..9a4c0d322 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_parameter_service/client.py @@ -0,0 +1,515 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ad_parameter_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdParameterServiceGrpcTransport + + +class AdParameterServiceClientMeta(type): + """Metaclass for the AdParameterService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdParameterServiceTransport]] + _transport_registry["grpc"] = AdParameterServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdParameterServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdParameterServiceClient(metaclass=AdParameterServiceClientMeta): + """Service to manage ad parameters.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdParameterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdParameterServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdParameterServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad parameter service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdParameterServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdParameterServiceTransport): + # transport is a AdParameterServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_ad_parameters( + self, + request: Union[ + ad_parameter_service.MutateAdParametersRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ad_parameter_service.AdParameterOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_parameter_service.MutateAdParametersResponse: + r"""Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdParametersRequest, dict]): + The request object. Request message for + [AdParameterService.MutateAdParameters][google.ads.googleads.v12.services.AdParameterService.MutateAdParameters] + customer_id (str): + Required. The ID of the customer + whose ad parameters are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdParameterOperation]): + Required. The list of operations to + perform on individual ad parameters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdParametersResponse: + Response message for an ad parameter + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_parameter_service.MutateAdParametersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, ad_parameter_service.MutateAdParametersRequest + ): + request = ad_parameter_service.MutateAdParametersRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_parameters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdParameterServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_parameter_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/__init__.py new file mode 100644 index 000000000..7a9de6077 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdParameterServiceTransport +from .grpc import AdParameterServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdParameterServiceTransport]] +_transport_registry["grpc"] = AdParameterServiceGrpcTransport + +__all__ = ( + "AdParameterServiceTransport", + "AdParameterServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_parameter_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/base.py new file mode 100644 index 000000000..ce5d8f160 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ad_parameter_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdParameterServiceTransport(abc.ABC): + """Abstract transport class for AdParameterService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_parameters: gapic_v1.method.wrap_method( + self.mutate_ad_parameters, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_parameters( + self, + ) -> Callable[ + [ad_parameter_service.MutateAdParametersRequest], + Union[ + ad_parameter_service.MutateAdParametersResponse, + Awaitable[ad_parameter_service.MutateAdParametersResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdParameterServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_parameter_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/grpc.py new file mode 100644 index 000000000..800afee37 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_parameter_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ad_parameter_service +from .base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO + + +class AdParameterServiceGrpcTransport(AdParameterServiceTransport): + """gRPC backend transport for AdParameterService. + + Service to manage ad parameters. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_ad_parameters( + self, + ) -> Callable[ + [ad_parameter_service.MutateAdParametersRequest], + ad_parameter_service.MutateAdParametersResponse, + ]: + r"""Return a callable for the mutate ad parameters method over gRPC. + + Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdParametersRequest], + ~.MutateAdParametersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_parameters" not in self._stubs: + self._stubs["mutate_ad_parameters"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdParameterService/MutateAdParameters", + request_serializer=ad_parameter_service.MutateAdParametersRequest.serialize, + response_deserializer=ad_parameter_service.MutateAdParametersResponse.deserialize, + ) + return self._stubs["mutate_ad_parameters"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdParameterServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_service/__init__.py b/google/ads/googleads/v12/services/services/ad_service/__init__.py new file mode 100644 index 000000000..7880d3db9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdServiceClient + +__all__ = ("AdServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_service/client.py b/google/ads/googleads/v12/services/services/ad_service/client.py new file mode 100644 index 000000000..8c17dd9c9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_service/client.py @@ -0,0 +1,568 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import ad +from google.ads.googleads.v12.services.types import ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdServiceGrpcTransport + + +class AdServiceClientMeta(type): + """Metaclass for the AdService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdServiceTransport]] + _transport_registry["grpc"] = AdServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AdServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdServiceClient(metaclass=AdServiceClientMeta): + """Service to manage ads.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_path(customer_id: str, ad_id: str,) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AdServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AdServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AdServiceTransport): + # transport is a AdServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def get_ad( + self, + request: Union[ad_service.GetAdRequest, dict] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad.Ad: + r"""Returns the requested ad in full detail. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GetAdRequest, dict]): + The request object. Request message for + [AdService.GetAd][google.ads.googleads.v12.services.AdService.GetAd]. + resource_name (str): + Required. The resource name of the ad + to fetch. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.resources.types.Ad: + An ad. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_service.GetAdRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, ad_service.GetAdRequest): + request = ad_service.GetAdRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_ad] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate_ads( + self, + request: Union[ad_service.MutateAdsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[ad_service.AdOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> ad_service.MutateAdsResponse: + r"""Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAdsRequest, dict]): + The request object. Request message for + [AdService.MutateAds][google.ads.googleads.v12.services.AdService.MutateAds]. + customer_id (str): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AdOperation]): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAdsResponse: + Response message for an ad mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a ad_service.MutateAdsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, ad_service.MutateAdsRequest): + request = ad_service.MutateAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_ads] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AdServiceClient",) diff --git a/google/ads/googleads/v12/services/services/ad_service/transports/__init__.py b/google/ads/googleads/v12/services/services/ad_service/transports/__init__.py new file mode 100644 index 000000000..617fcfabc --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_service/transports/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AdServiceTransport +from .grpc import AdServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[AdServiceTransport]] +_transport_registry["grpc"] = AdServiceGrpcTransport + +__all__ = ( + "AdServiceTransport", + "AdServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/ad_service/transports/base.py b/google/ads/googleads/v12/services/services/ad_service/transports/base.py new file mode 100644 index 000000000..2575a52fa --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_service/transports/base.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.resources.types import ad +from google.ads.googleads.v12.services.types import ad_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AdServiceTransport(abc.ABC): + """Abstract transport class for AdService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_ad: gapic_v1.method.wrap_method( + self.get_ad, default_timeout=None, client_info=client_info, + ), + self.mutate_ads: gapic_v1.method.wrap_method( + self.mutate_ads, default_timeout=None, client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def get_ad( + self, + ) -> Callable[[ad_service.GetAdRequest], Union[ad.Ad, Awaitable[ad.Ad]]]: + raise NotImplementedError() + + @property + def mutate_ads( + self, + ) -> Callable[ + [ad_service.MutateAdsRequest], + Union[ + ad_service.MutateAdsResponse, + Awaitable[ad_service.MutateAdsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AdServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/ad_service/transports/grpc.py b/google/ads/googleads/v12/services/services/ad_service/transports/grpc.py new file mode 100644 index 000000000..7f9c86bf7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/ad_service/transports/grpc.py @@ -0,0 +1,313 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.resources.types import ad +from google.ads.googleads.v12.services.types import ad_service +from .base import AdServiceTransport, DEFAULT_CLIENT_INFO + + +class AdServiceGrpcTransport(AdServiceTransport): + """gRPC backend transport for AdService. + + Service to manage ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def get_ad(self) -> Callable[[ad_service.GetAdRequest], ad.Ad]: + r"""Return a callable for the get ad method over gRPC. + + Returns the requested ad in full detail. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetAdRequest], + ~.Ad]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_ad" not in self._stubs: + self._stubs["get_ad"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdService/GetAd", + request_serializer=ad_service.GetAdRequest.serialize, + response_deserializer=ad.Ad.deserialize, + ) + return self._stubs["get_ad"] + + @property + def mutate_ads( + self, + ) -> Callable[[ad_service.MutateAdsRequest], ad_service.MutateAdsResponse]: + r"""Return a callable for the mutate ads method over gRPC. + + Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdsRequest], + ~.MutateAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ads" not in self._stubs: + self._stubs["mutate_ads"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AdService/MutateAds", + request_serializer=ad_service.MutateAdsRequest.serialize, + response_deserializer=ad_service.MutateAdsResponse.deserialize, + ) + return self._stubs["mutate_ads"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AdServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_asset_service/__init__.py b/google/ads/googleads/v12/services/services/asset_group_asset_service/__init__.py new file mode 100644 index 000000000..0a6f0c54b --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetGroupAssetServiceClient + +__all__ = ("AssetGroupAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_asset_service/client.py b/google/ads/googleads/v12/services/services/asset_group_asset_service/client.py new file mode 100644 index 000000000..bab264cbf --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_asset_service/client.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupAssetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupAssetServiceGrpcTransport + + +class AssetGroupAssetServiceClientMeta(type): + """Metaclass for the AssetGroupAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupAssetServiceTransport]] + _transport_registry["grpc"] = AssetGroupAssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetGroupAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupAssetServiceClient(metaclass=AssetGroupAssetServiceClientMeta): + """Service to manage asset group asset.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, asset_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetGroupAssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetGroupAssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetGroupAssetServiceTransport): + # transport is a AssetGroupAssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_group_assets( + self, + request: Union[ + asset_group_asset_service.MutateAssetGroupAssetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + asset_group_asset_service.AssetGroupAssetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_group_asset_service.MutateAssetGroupAssetsResponse: + r"""Creates, updates or removes asset group assets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetGroupAssetsRequest, dict]): + The request object. Request message for + [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v12.services.AssetGroupAssetService.MutateAssetGroupAssets]. + customer_id (str): + Required. The ID of the customer + whose asset group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupAssetOperation]): + Required. The list of operations to + perform on individual asset group + assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetGroupAssetsResponse: + Response message for an asset group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_group_asset_service.MutateAssetGroupAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, asset_group_asset_service.MutateAssetGroupAssetsRequest + ): + request = asset_group_asset_service.MutateAssetGroupAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetGroupAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/__init__.py new file mode 100644 index 000000000..ce5e8acc3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetGroupAssetServiceTransport +from .grpc import AssetGroupAssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetGroupAssetServiceTransport]] +_transport_registry["grpc"] = AssetGroupAssetServiceGrpcTransport + +__all__ = ( + "AssetGroupAssetServiceTransport", + "AssetGroupAssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/base.py new file mode 100644 index 000000000..7b10f44b2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetGroupAssetServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_assets: gapic_v1.method.wrap_method( + self.mutate_asset_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_assets( + self, + ) -> Callable[ + [asset_group_asset_service.MutateAssetGroupAssetsRequest], + Union[ + asset_group_asset_service.MutateAssetGroupAssetsResponse, + Awaitable[asset_group_asset_service.MutateAssetGroupAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/grpc.py new file mode 100644 index 000000000..a50456c43 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_asset_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_asset_service +from .base import AssetGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetGroupAssetServiceGrpcTransport(AssetGroupAssetServiceTransport): + """gRPC backend transport for AssetGroupAssetService. + + Service to manage asset group asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_group_assets( + self, + ) -> Callable[ + [asset_group_asset_service.MutateAssetGroupAssetsRequest], + asset_group_asset_service.MutateAssetGroupAssetsResponse, + ]: + r"""Return a callable for the mutate asset group assets method over gRPC. + + Creates, updates or removes asset group assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupAssetsRequest], + ~.MutateAssetGroupAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_assets" not in self._stubs: + self._stubs[ + "mutate_asset_group_assets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetGroupAssetService/MutateAssetGroupAssets", + request_serializer=asset_group_asset_service.MutateAssetGroupAssetsRequest.serialize, + response_deserializer=asset_group_asset_service.MutateAssetGroupAssetsResponse.deserialize, + ) + return self._stubs["mutate_asset_group_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/__init__.py b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/__init__.py new file mode 100644 index 000000000..c53f3f49f --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetGroupListingGroupFilterServiceClient + +__all__ = ("AssetGroupListingGroupFilterServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/client.py b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/client.py new file mode 100644 index 000000000..9547b0931 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/client.py @@ -0,0 +1,523 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + asset_group_listing_group_filter_service, +) +from .transports.base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupListingGroupFilterServiceGrpcTransport + + +class AssetGroupListingGroupFilterServiceClientMeta(type): + """Metaclass for the AssetGroupListingGroupFilterService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupListingGroupFilterServiceTransport]] + _transport_registry[ + "grpc" + ] = AssetGroupListingGroupFilterServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetGroupListingGroupFilterServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupListingGroupFilterServiceClient( + metaclass=AssetGroupListingGroupFilterServiceClientMeta +): + """Service to manage asset group listing group filter.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupListingGroupFilterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupListingGroupFilterServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, asset_group_id: str, listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, AssetGroupListingGroupFilterServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group listing group filter service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetGroupListingGroupFilterServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetGroupListingGroupFilterServiceTransport): + # transport is a AssetGroupListingGroupFilterServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_group_listing_group_filters( + self, + request: Union[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse: + r"""Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetGroupListingGroupFiltersRequest, dict]): + The request object. Request message for + [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v12.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. + partial_failure is not supported because the tree needs + to be validated together. + customer_id (str): + Required. The ID of the customer + whose asset group listing group filters + are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupListingGroupFilterOperation]): + Required. The list of operations to + perform on individual asset group + listing group filters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetGroupListingGroupFiltersResponse: + Response message for an asset group + listing group filter mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + ): + request = asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_listing_group_filters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetGroupListingGroupFilterServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/__init__.py new file mode 100644 index 000000000..159ef2f06 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetGroupListingGroupFilterServiceTransport +from .grpc import AssetGroupListingGroupFilterServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetGroupListingGroupFilterServiceTransport]] +_transport_registry["grpc"] = AssetGroupListingGroupFilterServiceGrpcTransport + +__all__ = ( + "AssetGroupListingGroupFilterServiceTransport", + "AssetGroupListingGroupFilterServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/base.py new file mode 100644 index 000000000..23e38ad01 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + asset_group_listing_group_filter_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetGroupListingGroupFilterServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupListingGroupFilterService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_listing_group_filters: gapic_v1.method.wrap_method( + self.mutate_asset_group_listing_group_filters, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_listing_group_filters( + self, + ) -> Callable[ + [ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest + ], + Union[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, + Awaitable[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetGroupListingGroupFilterServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/grpc.py new file mode 100644 index 000000000..28fd08ea5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_listing_group_filter_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + asset_group_listing_group_filter_service, +) +from .base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class AssetGroupListingGroupFilterServiceGrpcTransport( + AssetGroupListingGroupFilterServiceTransport +): + """gRPC backend transport for AssetGroupListingGroupFilterService. + + Service to manage asset group listing group filter. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_group_listing_group_filters( + self, + ) -> Callable[ + [ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest + ], + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, + ]: + r"""Return a callable for the mutate asset group listing + group filters method over gRPC. + + Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupListingGroupFiltersRequest], + ~.MutateAssetGroupListingGroupFiltersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_listing_group_filters" not in self._stubs: + self._stubs[ + "mutate_asset_group_listing_group_filters" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetGroupListingGroupFilterService/MutateAssetGroupListingGroupFilters", + request_serializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest.serialize, + response_deserializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse.deserialize, + ) + return self._stubs["mutate_asset_group_listing_group_filters"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetGroupListingGroupFilterServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_service/__init__.py b/google/ads/googleads/v12/services/services/asset_group_service/__init__.py new file mode 100644 index 000000000..df6bf85e5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetGroupServiceClient + +__all__ = ("AssetGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_service/client.py b/google/ads/googleads/v12/services/services/asset_group_service/client.py new file mode 100644 index 000000000..55847f5b3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_service/client.py @@ -0,0 +1,497 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetGroupServiceGrpcTransport + + +class AssetGroupServiceClientMeta(type): + """Metaclass for the AssetGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupServiceTransport]] + _transport_registry["grpc"] = AssetGroupServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupServiceClient(metaclass=AssetGroupServiceClientMeta): + """Service to manage asset group""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetGroupServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetGroupServiceTransport): + # transport is a AssetGroupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_groups( + self, + request: Union[ + asset_group_service.MutateAssetGroupsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[asset_group_service.AssetGroupOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_group_service.MutateAssetGroupsResponse: + r"""Creates, updates or removes asset groups. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetGroupsRequest, dict]): + The request object. Request message for + [AssetGroupService.MutateAssetGroups][google.ads.googleads.v12.services.AssetGroupService.MutateAssetGroups]. + customer_id (str): + Required. The ID of the customer + whose asset groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupOperation]): + Required. The list of operations to + perform on individual asset groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetGroupsResponse: + Response message for an asset group + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_group_service.MutateAssetGroupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, asset_group_service.MutateAssetGroupsRequest + ): + request = asset_group_service.MutateAssetGroupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_group_service/transports/__init__.py new file mode 100644 index 000000000..123f76b84 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetGroupServiceTransport +from .grpc import AssetGroupServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetGroupServiceTransport]] +_transport_registry["grpc"] = AssetGroupServiceGrpcTransport + +__all__ = ( + "AssetGroupServiceTransport", + "AssetGroupServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_group_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_group_service/transports/base.py new file mode 100644 index 000000000..f54ebb579 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetGroupServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_groups: gapic_v1.method.wrap_method( + self.mutate_asset_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_groups( + self, + ) -> Callable[ + [asset_group_service.MutateAssetGroupsRequest], + Union[ + asset_group_service.MutateAssetGroupsResponse, + Awaitable[asset_group_service.MutateAssetGroupsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetGroupServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_group_service/transports/grpc.py new file mode 100644 index 000000000..1f8b504ee --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_service/transports/grpc.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_service +from .base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetGroupServiceGrpcTransport(AssetGroupServiceTransport): + """gRPC backend transport for AssetGroupService. + + Service to manage asset group + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_groups( + self, + ) -> Callable[ + [asset_group_service.MutateAssetGroupsRequest], + asset_group_service.MutateAssetGroupsResponse, + ]: + r"""Return a callable for the mutate asset groups method over gRPC. + + Creates, updates or removes asset groups. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupsRequest], + ~.MutateAssetGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_groups" not in self._stubs: + self._stubs["mutate_asset_groups"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetGroupService/MutateAssetGroups", + request_serializer=asset_group_service.MutateAssetGroupsRequest.serialize, + response_deserializer=asset_group_service.MutateAssetGroupsResponse.deserialize, + ) + return self._stubs["mutate_asset_groups"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_signal_service/__init__.py b/google/ads/googleads/v12/services/services/asset_group_signal_service/__init__.py new file mode 100644 index 000000000..99a25329d --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_signal_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetGroupSignalServiceClient + +__all__ = ("AssetGroupSignalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_signal_service/client.py b/google/ads/googleads/v12/services/services/asset_group_signal_service/client.py new file mode 100644 index 000000000..443285fac --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_signal_service/client.py @@ -0,0 +1,512 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_signal_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupSignalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupSignalServiceGrpcTransport + + +class AssetGroupSignalServiceClientMeta(type): + """Metaclass for the AssetGroupSignalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupSignalServiceTransport]] + _transport_registry["grpc"] = AssetGroupSignalServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetGroupSignalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupSignalServiceClient( + metaclass=AssetGroupSignalServiceClientMeta +): + """Service to manage asset group signal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupSignalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupSignalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, asset_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetGroupSignalServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group signal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetGroupSignalServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetGroupSignalServiceTransport): + # transport is a AssetGroupSignalServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_group_signals( + self, + request: Union[ + asset_group_signal_service.MutateAssetGroupSignalsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + asset_group_signal_service.AssetGroupSignalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_group_signal_service.MutateAssetGroupSignalsResponse: + r"""Creates or removes asset group signals. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetGroupSignalsRequest, dict]): + The request object. Request message for + [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v12.services.AssetGroupSignalService.MutateAssetGroupSignals]. + customer_id (str): + Required. The ID of the customer + whose asset group signals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupSignalOperation]): + Required. The list of operations to + perform on individual asset group + signals. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetGroupSignalsResponse: + Response message for an asset group + signal mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_group_signal_service.MutateAssetGroupSignalsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, asset_group_signal_service.MutateAssetGroupSignalsRequest + ): + request = asset_group_signal_service.MutateAssetGroupSignalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_signals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetGroupSignalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/__init__.py new file mode 100644 index 000000000..9b57f4d6a --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetGroupSignalServiceTransport +from .grpc import AssetGroupSignalServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetGroupSignalServiceTransport]] +_transport_registry["grpc"] = AssetGroupSignalServiceGrpcTransport + +__all__ = ( + "AssetGroupSignalServiceTransport", + "AssetGroupSignalServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/base.py new file mode 100644 index 000000000..c4fcfe1be --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_signal_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetGroupSignalServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupSignalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_signals: gapic_v1.method.wrap_method( + self.mutate_asset_group_signals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_signals( + self, + ) -> Callable[ + [asset_group_signal_service.MutateAssetGroupSignalsRequest], + Union[ + asset_group_signal_service.MutateAssetGroupSignalsResponse, + Awaitable[ + asset_group_signal_service.MutateAssetGroupSignalsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetGroupSignalServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/grpc.py new file mode 100644 index 000000000..40c103772 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_group_signal_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_group_signal_service +from .base import AssetGroupSignalServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetGroupSignalServiceGrpcTransport(AssetGroupSignalServiceTransport): + """gRPC backend transport for AssetGroupSignalService. + + Service to manage asset group signal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_group_signals( + self, + ) -> Callable[ + [asset_group_signal_service.MutateAssetGroupSignalsRequest], + asset_group_signal_service.MutateAssetGroupSignalsResponse, + ]: + r"""Return a callable for the mutate asset group signals method over gRPC. + + Creates or removes asset group signals. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupSignalsRequest], + ~.MutateAssetGroupSignalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_signals" not in self._stubs: + self._stubs[ + "mutate_asset_group_signals" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetGroupSignalService/MutateAssetGroupSignals", + request_serializer=asset_group_signal_service.MutateAssetGroupSignalsRequest.serialize, + response_deserializer=asset_group_signal_service.MutateAssetGroupSignalsResponse.deserialize, + ) + return self._stubs["mutate_asset_group_signals"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetGroupSignalServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_service/__init__.py b/google/ads/googleads/v12/services/services/asset_service/__init__.py new file mode 100644 index 000000000..e302d8c39 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetServiceClient + +__all__ = ("AssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_service/client.py b/google/ads/googleads/v12/services/services/asset_service/client.py new file mode 100644 index 000000000..1526669f1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_service/client.py @@ -0,0 +1,505 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetServiceGrpcTransport + + +class AssetServiceClientMeta(type): + """Metaclass for the AssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetServiceTransport]] + _transport_registry["grpc"] = AssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetServiceClient(metaclass=AssetServiceClientMeta): + """Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetServiceTransport): + # transport is a AssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_assets( + self, + request: Union[asset_service.MutateAssetsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[asset_service.AssetOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_service.MutateAssetsResponse: + r"""Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetsRequest, dict]): + The request object. Request message for + [AssetService.MutateAssets][google.ads.googleads.v12.services.AssetService.MutateAssets] + customer_id (str): + Required. The ID of the customer + whose assets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetOperation]): + Required. The list of operations to + perform on individual assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetsResponse: + Response message for an asset mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_service.MutateAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, asset_service.MutateAssetsRequest): + request = asset_service.MutateAssetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_assets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_service/transports/__init__.py new file mode 100644 index 000000000..f456a5c77 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetServiceTransport +from .grpc import AssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetServiceTransport]] +_transport_registry["grpc"] = AssetServiceGrpcTransport + +__all__ = ( + "AssetServiceTransport", + "AssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_service/transports/base.py new file mode 100644 index 000000000..60cb03d31 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetServiceTransport(abc.ABC): + """Abstract transport class for AssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_assets: gapic_v1.method.wrap_method( + self.mutate_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_assets( + self, + ) -> Callable[ + [asset_service.MutateAssetsRequest], + Union[ + asset_service.MutateAssetsResponse, + Awaitable[asset_service.MutateAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_service/transports/grpc.py new file mode 100644 index 000000000..11943df70 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_service/transports/grpc.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_service +from .base import AssetServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetServiceGrpcTransport(AssetServiceTransport): + """gRPC backend transport for AssetService. + + Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_assets( + self, + ) -> Callable[ + [asset_service.MutateAssetsRequest], asset_service.MutateAssetsResponse + ]: + r"""Return a callable for the mutate assets method over gRPC. + + Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateAssetsRequest], + ~.MutateAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_assets" not in self._stubs: + self._stubs["mutate_assets"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetService/MutateAssets", + request_serializer=asset_service.MutateAssetsRequest.serialize, + response_deserializer=asset_service.MutateAssetsResponse.deserialize, + ) + return self._stubs["mutate_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_set_asset_service/__init__.py b/google/ads/googleads/v12/services/services/asset_set_asset_service/__init__.py new file mode 100644 index 000000000..03550f56e --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetSetAssetServiceClient + +__all__ = ("AssetSetAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_set_asset_service/client.py b/google/ads/googleads/v12/services/services/asset_set_asset_service/client.py new file mode 100644 index 000000000..1d507dde1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_asset_service/client.py @@ -0,0 +1,521 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetSetAssetServiceGrpcTransport + + +class AssetSetAssetServiceClientMeta(type): + """Metaclass for the AssetSetAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetSetAssetServiceTransport]] + _transport_registry["grpc"] = AssetSetAssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetSetAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetSetAssetServiceClient(metaclass=AssetSetAssetServiceClientMeta): + """Service to manage asset set asset.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetSetAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, asset_set_id: str, asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetSetAssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetSetAssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetSetAssetServiceTransport): + # transport is a AssetSetAssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_set_assets( + self, + request: Union[ + asset_set_asset_service.MutateAssetSetAssetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + asset_set_asset_service.AssetSetAssetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_set_asset_service.MutateAssetSetAssetsResponse: + r"""Creates, updates or removes asset set assets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetSetAssetsRequest, dict]): + The request object. Request message for + [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v12.services.AssetSetAssetService.MutateAssetSetAssets]. + customer_id (str): + Required. The ID of the customer + whose asset set assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetSetAssetOperation]): + Required. The list of operations to + perform on individual asset set assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetSetAssetsResponse: + Response message for an asset set + asset mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_set_asset_service.MutateAssetSetAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, asset_set_asset_service.MutateAssetSetAssetsRequest + ): + request = asset_set_asset_service.MutateAssetSetAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_set_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetSetAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/__init__.py new file mode 100644 index 000000000..f11484109 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetSetAssetServiceTransport +from .grpc import AssetSetAssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetSetAssetServiceTransport]] +_transport_registry["grpc"] = AssetSetAssetServiceGrpcTransport + +__all__ = ( + "AssetSetAssetServiceTransport", + "AssetSetAssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/base.py new file mode 100644 index 000000000..6f2ba1f64 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetSetAssetServiceTransport(abc.ABC): + """Abstract transport class for AssetSetAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_set_assets: gapic_v1.method.wrap_method( + self.mutate_asset_set_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_set_assets( + self, + ) -> Callable[ + [asset_set_asset_service.MutateAssetSetAssetsRequest], + Union[ + asset_set_asset_service.MutateAssetSetAssetsResponse, + Awaitable[asset_set_asset_service.MutateAssetSetAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetSetAssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/grpc.py new file mode 100644 index 000000000..a4a61dc5e --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_asset_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_asset_service +from .base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetSetAssetServiceGrpcTransport(AssetSetAssetServiceTransport): + """gRPC backend transport for AssetSetAssetService. + + Service to manage asset set asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_set_assets( + self, + ) -> Callable[ + [asset_set_asset_service.MutateAssetSetAssetsRequest], + asset_set_asset_service.MutateAssetSetAssetsResponse, + ]: + r"""Return a callable for the mutate asset set assets method over gRPC. + + Creates, updates or removes asset set assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetSetAssetsRequest], + ~.MutateAssetSetAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_set_assets" not in self._stubs: + self._stubs[ + "mutate_asset_set_assets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetSetAssetService/MutateAssetSetAssets", + request_serializer=asset_set_asset_service.MutateAssetSetAssetsRequest.serialize, + response_deserializer=asset_set_asset_service.MutateAssetSetAssetsResponse.deserialize, + ) + return self._stubs["mutate_asset_set_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetSetAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_set_service/__init__.py b/google/ads/googleads/v12/services/services/asset_set_service/__init__.py new file mode 100644 index 000000000..4fa8475b0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AssetSetServiceClient + +__all__ = ("AssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_set_service/client.py b/google/ads/googleads/v12/services/services/asset_set_service/client.py new file mode 100644 index 000000000..8baae6e4c --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_service/client.py @@ -0,0 +1,477 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetSetServiceGrpcTransport + + +class AssetSetServiceClientMeta(type): + """Metaclass for the AssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetSetServiceTransport]] + _transport_registry["grpc"] = AssetSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetSetServiceClient(metaclass=AssetSetServiceClientMeta): + """Service to manage asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AssetSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AssetSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AssetSetServiceTransport): + # transport is a AssetSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_asset_sets( + self, + request: Union[asset_set_service.MutateAssetSetsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[asset_set_service.AssetSetOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_set_service.MutateAssetSetsResponse: + r"""Creates, updates or removes asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAssetSetsRequest, dict]): + The request object. Request message for + [AssetSetService.MutateAssetSets][google.ads.googleads.v12.services.AssetSetService.MutateAssetSets]. + customer_id (str): + Required. The ID of the customer + whose asset sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AssetSetOperation]): + Required. The list of operations to + perform on individual asset sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAssetSetsResponse: + Response message for an asset set + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a asset_set_service.MutateAssetSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, asset_set_service.MutateAssetSetsRequest): + request = asset_set_service.MutateAssetSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/asset_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/asset_set_service/transports/__init__.py new file mode 100644 index 000000000..31d8ddd2f --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AssetSetServiceTransport +from .grpc import AssetSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetSetServiceTransport]] +_transport_registry["grpc"] = AssetSetServiceGrpcTransport + +__all__ = ( + "AssetSetServiceTransport", + "AssetSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/asset_set_service/transports/base.py b/google/ads/googleads/v12/services/services/asset_set_service/transports/base.py new file mode 100644 index 000000000..9f9d87ffc --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AssetSetServiceTransport(abc.ABC): + """Abstract transport class for AssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_sets: gapic_v1.method.wrap_method( + self.mutate_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_sets( + self, + ) -> Callable[ + [asset_set_service.MutateAssetSetsRequest], + Union[ + asset_set_service.MutateAssetSetsResponse, + Awaitable[asset_set_service.MutateAssetSetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AssetSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/asset_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/asset_set_service/transports/grpc.py new file mode 100644 index 000000000..062e1bda2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/asset_set_service/transports/grpc.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import asset_set_service +from .base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO + + +class AssetSetServiceGrpcTransport(AssetSetServiceTransport): + """gRPC backend transport for AssetSetService. + + Service to manage asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_asset_sets( + self, + ) -> Callable[ + [asset_set_service.MutateAssetSetsRequest], + asset_set_service.MutateAssetSetsResponse, + ]: + r"""Return a callable for the mutate asset sets method over gRPC. + + Creates, updates or removes asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetSetsRequest], + ~.MutateAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_sets" not in self._stubs: + self._stubs["mutate_asset_sets"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AssetSetService/MutateAssetSets", + request_serializer=asset_set_service.MutateAssetSetsRequest.serialize, + response_deserializer=asset_set_service.MutateAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_asset_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/audience_insights_service/__init__.py b/google/ads/googleads/v12/services/services/audience_insights_service/__init__.py new file mode 100644 index 000000000..d1aebe6fa --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_insights_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AudienceInsightsServiceClient + +__all__ = ("AudienceInsightsServiceClient",) diff --git a/google/ads/googleads/v12/services/services/audience_insights_service/client.py b/google/ads/googleads/v12/services/services/audience_insights_service/client.py new file mode 100644 index 000000000..ac60c8c2f --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_insights_service/client.py @@ -0,0 +1,781 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.enums.types import audience_insights_dimension +from google.ads.googleads.v12.services.types import audience_insights_service +from .transports.base import ( + AudienceInsightsServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AudienceInsightsServiceGrpcTransport + + +class AudienceInsightsServiceClientMeta(type): + """Metaclass for the AudienceInsightsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AudienceInsightsServiceTransport]] + _transport_registry["grpc"] = AudienceInsightsServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AudienceInsightsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AudienceInsightsServiceClient( + metaclass=AudienceInsightsServiceClientMeta +): + """Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + """ + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AudienceInsightsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceInsightsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AudienceInsightsServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience insights service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AudienceInsightsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AudienceInsightsServiceTransport): + # transport is a AudienceInsightsServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def generate_insights_finder_report( + self, + request: Union[ + audience_insights_service.GenerateInsightsFinderReportRequest, dict + ] = None, + *, + customer_id: str = None, + baseline_audience: audience_insights_service.BasicInsightsAudience = None, + specific_audience: audience_insights_service.BasicInsightsAudience = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> audience_insights_service.GenerateInsightsFinderReportResponse: + r"""Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateInsightsFinderReportRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v12.services.AudienceInsightsService.GenerateInsightsFinderReport]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + baseline_audience (google.ads.googleads.v12.services.types.BasicInsightsAudience): + Required. A baseline audience for + this report, typically all people in a + region. + + This corresponds to the ``baseline_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + specific_audience (google.ads.googleads.v12.services.types.BasicInsightsAudience): + Required. The specific audience of + interest for this report. The insights + in the report will be based on + attributes more prevalent in this + audience than in the report's baseline + audience. + + This corresponds to the ``specific_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateInsightsFinderReportResponse: + The response message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v12.services.AudienceInsightsService.GenerateInsightsFinderReport], + containing the shareable URL for the report. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [customer_id, baseline_audience, specific_audience] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a audience_insights_service.GenerateInsightsFinderReportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + audience_insights_service.GenerateInsightsFinderReportRequest, + ): + request = audience_insights_service.GenerateInsightsFinderReportRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if baseline_audience is not None: + request.baseline_audience = baseline_audience + if specific_audience is not None: + request.specific_audience = specific_audience + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_insights_finder_report + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_audience_insights_attributes( + self, + request: Union[ + audience_insights_service.ListAudienceInsightsAttributesRequest, + dict, + ] = None, + *, + customer_id: str = None, + dimensions: Sequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = None, + query_text: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> audience_insights_service.ListAudienceInsightsAttributesResponse: + r"""Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListAudienceInsightsAttributesRequest, dict]): + The request object. Request message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v12.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (Sequence[google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes to + be returned. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query_text (str): + Required. A free text query. + Attributes matching or related to this + string will be returned. + + This corresponds to the ``query_text`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListAudienceInsightsAttributesResponse: + Response message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v12.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, dimensions, query_text]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a audience_insights_service.ListAudienceInsightsAttributesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + audience_insights_service.ListAudienceInsightsAttributesRequest, + ): + request = audience_insights_service.ListAudienceInsightsAttributesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if dimensions is not None: + request.dimensions = dimensions + if query_text is not None: + request.query_text = query_text + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_audience_insights_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_insights_eligible_dates( + self, + request: Union[ + audience_insights_service.ListInsightsEligibleDatesRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> audience_insights_service.ListInsightsEligibleDatesResponse: + r"""Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListInsightsEligibleDatesRequest, dict]): + The request object. Request message for + [AudienceInsightsService.ListAudienceInsightsDates][]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListInsightsEligibleDatesResponse: + Response message for + [AudienceInsightsService.ListAudienceInsightsDates][]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a audience_insights_service.ListInsightsEligibleDatesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, audience_insights_service.ListInsightsEligibleDatesRequest + ): + request = audience_insights_service.ListInsightsEligibleDatesRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_insights_eligible_dates + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_audience_composition_insights( + self, + request: Union[ + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + dict, + ] = None, + *, + customer_id: str = None, + audience: audience_insights_service.InsightsAudience = None, + dimensions: Sequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> audience_insights_service.GenerateAudienceCompositionInsightsResponse: + r"""Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateAudienceCompositionInsightsRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v12.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audience (google.ads.googleads.v12.services.types.InsightsAudience): + Required. The audience of interest + for which insights are being requested. + + This corresponds to the ``audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (Sequence[google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The audience dimensions for + which composition insights should be + returned. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateAudienceCompositionInsightsResponse: + Response message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v12.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, audience, dimensions]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a audience_insights_service.GenerateAudienceCompositionInsightsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + ): + request = audience_insights_service.GenerateAudienceCompositionInsightsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audience is not None: + request.audience = audience + if dimensions is not None: + request.dimensions = dimensions + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_audience_composition_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AudienceInsightsServiceClient",) diff --git a/google/ads/googleads/v12/services/services/audience_insights_service/transports/__init__.py b/google/ads/googleads/v12/services/services/audience_insights_service/transports/__init__.py new file mode 100644 index 000000000..c2d04e972 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_insights_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AudienceInsightsServiceTransport +from .grpc import AudienceInsightsServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AudienceInsightsServiceTransport]] +_transport_registry["grpc"] = AudienceInsightsServiceGrpcTransport + +__all__ = ( + "AudienceInsightsServiceTransport", + "AudienceInsightsServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/audience_insights_service/transports/base.py b/google/ads/googleads/v12/services/services/audience_insights_service/transports/base.py new file mode 100644 index 000000000..a4de5a5d0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_insights_service/transports/base.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import audience_insights_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AudienceInsightsServiceTransport(abc.ABC): + """Abstract transport class for AudienceInsightsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_insights_finder_report: gapic_v1.method.wrap_method( + self.generate_insights_finder_report, + default_timeout=None, + client_info=client_info, + ), + self.list_audience_insights_attributes: gapic_v1.method.wrap_method( + self.list_audience_insights_attributes, + default_timeout=None, + client_info=client_info, + ), + self.list_insights_eligible_dates: gapic_v1.method.wrap_method( + self.list_insights_eligible_dates, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_composition_insights: gapic_v1.method.wrap_method( + self.generate_audience_composition_insights, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_insights_finder_report( + self, + ) -> Callable[ + [audience_insights_service.GenerateInsightsFinderReportRequest], + Union[ + audience_insights_service.GenerateInsightsFinderReportResponse, + Awaitable[ + audience_insights_service.GenerateInsightsFinderReportResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def list_audience_insights_attributes( + self, + ) -> Callable[ + [audience_insights_service.ListAudienceInsightsAttributesRequest], + Union[ + audience_insights_service.ListAudienceInsightsAttributesResponse, + Awaitable[ + audience_insights_service.ListAudienceInsightsAttributesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def list_insights_eligible_dates( + self, + ) -> Callable[ + [audience_insights_service.ListInsightsEligibleDatesRequest], + Union[ + audience_insights_service.ListInsightsEligibleDatesResponse, + Awaitable[ + audience_insights_service.ListInsightsEligibleDatesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_audience_composition_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceCompositionInsightsRequest], + Union[ + audience_insights_service.GenerateAudienceCompositionInsightsResponse, + Awaitable[ + audience_insights_service.GenerateAudienceCompositionInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AudienceInsightsServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/audience_insights_service/transports/grpc.py b/google/ads/googleads/v12/services/services/audience_insights_service/transports/grpc.py new file mode 100644 index 000000000..c7e99a789 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_insights_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import audience_insights_service +from .base import AudienceInsightsServiceTransport, DEFAULT_CLIENT_INFO + + +class AudienceInsightsServiceGrpcTransport(AudienceInsightsServiceTransport): + """gRPC backend transport for AudienceInsightsService. + + Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def generate_insights_finder_report( + self, + ) -> Callable[ + [audience_insights_service.GenerateInsightsFinderReportRequest], + audience_insights_service.GenerateInsightsFinderReportResponse, + ]: + r"""Return a callable for the generate insights finder + report method over gRPC. + + Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateInsightsFinderReportRequest], + ~.GenerateInsightsFinderReportResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_insights_finder_report" not in self._stubs: + self._stubs[ + "generate_insights_finder_report" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AudienceInsightsService/GenerateInsightsFinderReport", + request_serializer=audience_insights_service.GenerateInsightsFinderReportRequest.serialize, + response_deserializer=audience_insights_service.GenerateInsightsFinderReportResponse.deserialize, + ) + return self._stubs["generate_insights_finder_report"] + + @property + def list_audience_insights_attributes( + self, + ) -> Callable[ + [audience_insights_service.ListAudienceInsightsAttributesRequest], + audience_insights_service.ListAudienceInsightsAttributesResponse, + ]: + r"""Return a callable for the list audience insights + attributes method over gRPC. + + Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListAudienceInsightsAttributesRequest], + ~.ListAudienceInsightsAttributesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_audience_insights_attributes" not in self._stubs: + self._stubs[ + "list_audience_insights_attributes" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AudienceInsightsService/ListAudienceInsightsAttributes", + request_serializer=audience_insights_service.ListAudienceInsightsAttributesRequest.serialize, + response_deserializer=audience_insights_service.ListAudienceInsightsAttributesResponse.deserialize, + ) + return self._stubs["list_audience_insights_attributes"] + + @property + def list_insights_eligible_dates( + self, + ) -> Callable[ + [audience_insights_service.ListInsightsEligibleDatesRequest], + audience_insights_service.ListInsightsEligibleDatesResponse, + ]: + r"""Return a callable for the list insights eligible dates method over gRPC. + + Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInsightsEligibleDatesRequest], + ~.ListInsightsEligibleDatesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_insights_eligible_dates" not in self._stubs: + self._stubs[ + "list_insights_eligible_dates" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AudienceInsightsService/ListInsightsEligibleDates", + request_serializer=audience_insights_service.ListInsightsEligibleDatesRequest.serialize, + response_deserializer=audience_insights_service.ListInsightsEligibleDatesResponse.deserialize, + ) + return self._stubs["list_insights_eligible_dates"] + + @property + def generate_audience_composition_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceCompositionInsightsRequest], + audience_insights_service.GenerateAudienceCompositionInsightsResponse, + ]: + r"""Return a callable for the generate audience composition + insights method over gRPC. + + Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceCompositionInsightsRequest], + ~.GenerateAudienceCompositionInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_composition_insights" not in self._stubs: + self._stubs[ + "generate_audience_composition_insights" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AudienceInsightsService/GenerateAudienceCompositionInsights", + request_serializer=audience_insights_service.GenerateAudienceCompositionInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceCompositionInsightsResponse.deserialize, + ) + return self._stubs["generate_audience_composition_insights"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AudienceInsightsServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/audience_service/__init__.py b/google/ads/googleads/v12/services/services/audience_service/__init__.py new file mode 100644 index 000000000..55250d5eb --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AudienceServiceClient + +__all__ = ("AudienceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/audience_service/client.py b/google/ads/googleads/v12/services/services/audience_service/client.py new file mode 100644 index 000000000..f07429ae5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_service/client.py @@ -0,0 +1,476 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import audience_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AudienceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AudienceServiceGrpcTransport + + +class AudienceServiceClientMeta(type): + """Metaclass for the AudienceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AudienceServiceTransport]] + _transport_registry["grpc"] = AudienceServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[AudienceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AudienceServiceClient(metaclass=AudienceServiceClientMeta): + """Service to manage audiences.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def audience_path(customer_id: str, audience_id: str,) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, AudienceServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, AudienceServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, AudienceServiceTransport): + # transport is a AudienceServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_audiences( + self, + request: Union[audience_service.MutateAudiencesRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[audience_service.AudienceOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> audience_service.MutateAudiencesResponse: + r"""Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateAudiencesRequest, dict]): + The request object. Request message for + [AudienceService.MutateAudiences][google.ads.googleads.v12.services.AudienceService.MutateAudiences]. + customer_id (str): + Required. The ID of the customer + whose audiences are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.AudienceOperation]): + Required. The list of operations to + perform on individual audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateAudiencesResponse: + Response message for an audience + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a audience_service.MutateAudiencesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, audience_service.MutateAudiencesRequest): + request = audience_service.MutateAudiencesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_audiences] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("AudienceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/audience_service/transports/__init__.py b/google/ads/googleads/v12/services/services/audience_service/transports/__init__.py new file mode 100644 index 000000000..7968242f1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 AudienceServiceTransport +from .grpc import AudienceServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AudienceServiceTransport]] +_transport_registry["grpc"] = AudienceServiceGrpcTransport + +__all__ = ( + "AudienceServiceTransport", + "AudienceServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/audience_service/transports/base.py b/google/ads/googleads/v12/services/services/audience_service/transports/base.py new file mode 100644 index 000000000..628e29d80 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import audience_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class AudienceServiceTransport(abc.ABC): + """Abstract transport class for AudienceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_audiences: gapic_v1.method.wrap_method( + self.mutate_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_audiences( + self, + ) -> Callable[ + [audience_service.MutateAudiencesRequest], + Union[ + audience_service.MutateAudiencesResponse, + Awaitable[audience_service.MutateAudiencesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("AudienceServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/audience_service/transports/grpc.py b/google/ads/googleads/v12/services/services/audience_service/transports/grpc.py new file mode 100644 index 000000000..2c1c073f6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/audience_service/transports/grpc.py @@ -0,0 +1,270 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import audience_service +from .base import AudienceServiceTransport, DEFAULT_CLIENT_INFO + + +class AudienceServiceGrpcTransport(AudienceServiceTransport): + """gRPC backend transport for AudienceService. + + Service to manage audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_audiences( + self, + ) -> Callable[ + [audience_service.MutateAudiencesRequest], + audience_service.MutateAudiencesResponse, + ]: + r"""Return a callable for the mutate audiences method over gRPC. + + Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Returns: + Callable[[~.MutateAudiencesRequest], + ~.MutateAudiencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_audiences" not in self._stubs: + self._stubs["mutate_audiences"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.AudienceService/MutateAudiences", + request_serializer=audience_service.MutateAudiencesRequest.serialize, + response_deserializer=audience_service.MutateAudiencesResponse.deserialize, + ) + return self._stubs["mutate_audiences"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("AudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/__init__.py b/google/ads/googleads/v12/services/services/batch_job_service/__init__.py new file mode 100644 index 000000000..00ce4ce46 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BatchJobServiceClient + +__all__ = ("BatchJobServiceClient",) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/client.py b/google/ads/googleads/v12/services/services/batch_job_service/client.py new file mode 100644 index 000000000..5de70f835 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/client.py @@ -0,0 +1,2257 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import batch_job +from google.ads.googleads.v12.services.services.batch_job_service import pagers +from google.ads.googleads.v12.services.types import batch_job_service +from google.ads.googleads.v12.services.types import google_ads_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .transports.base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import BatchJobServiceGrpcTransport + + +class BatchJobServiceClientMeta(type): + """Metaclass for the BatchJobService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BatchJobServiceTransport]] + _transport_registry["grpc"] = BatchJobServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[BatchJobServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BatchJobServiceClient(metaclass=BatchJobServiceClientMeta): + """Service to manage batch jobs.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BatchJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BatchJobServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_path(customer_id: str, ad_id: str,) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, ad_group_id: str, ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, ad_group_id: str, ad_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, ad_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, ad_group_id: str, criterion_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, ad_group_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_extension_setting_path( + customer_id: str, ad_group_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified ad_group_extension_setting string.""" + return "customers/{customer_id}/adGroupExtensionSettings/{ad_group_id}~{extension_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_ad_group_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a ad_group_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_feed_path( + customer_id: str, ad_group_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified ad_group_feed string.""" + return "customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, feed_id=feed_id, + ) + + @staticmethod + def parse_ad_group_feed_path(path: str) -> Dict[str, str]: + """Parses a ad_group_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, ad_group_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, asset_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, asset_group_id: str, listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, asset_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, asset_set_id: str, asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_path(customer_id: str, audience_id: str,) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def batch_job_path(customer_id: str, batch_job_id: str,) -> str: + """Returns a fully-qualified batch_job string.""" + return "customers/{customer_id}/batchJobs/{batch_job_id}".format( + customer_id=customer_id, batch_job_id=batch_job_id, + ) + + @staticmethod + def parse_batch_job_path(path: str) -> Dict[str, str]: + """Parses a batch_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/batchJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, campaign_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, campaign_id: str, asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path(customer_id: str, campaign_budget_id: str,) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, campaign_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, campaign_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, base_campaign_id: str, draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_extension_setting_path( + customer_id: str, campaign_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified campaign_extension_setting string.""" + return "customers/{customer_id}/campaignExtensionSettings/{campaign_id}~{extension_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_campaign_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a campaign_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_feed_path( + customer_id: str, campaign_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified campaign_feed string.""" + return "customers/{customer_id}/campaignFeeds/{campaign_id}~{feed_id}".format( + customer_id=customer_id, campaign_id=campaign_id, feed_id=feed_id, + ) + + @staticmethod + def parse_campaign_feed_path(path: str) -> Dict[str, str]: + """Parses a campaign_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path(customer_id: str, campaign_group_id: str,) -> str: + """Returns a fully-qualified campaign_group string.""" + return "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, campaign_group_id=campaign_group_id, + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, campaign_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, campaign_id=campaign_id, label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, campaign_id: str, shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path(customer_id: str, goal_id: str,) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, asset_id=asset_id, field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, category=category, source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_customizer_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_extension_setting_path( + customer_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified customer_extension_setting string.""" + return "customers/{customer_id}/customerExtensionSettings/{extension_type}".format( + customer_id=customer_id, extension_type=extension_type, + ) + + @staticmethod + def parse_customer_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a customer_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerExtensionSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified customer_feed string.""" + return "customers/{customer_id}/customerFeeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_customer_feed_path(path: str) -> Dict[str, str]: + """Parses a customer_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerFeeds/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(customer_id: str, trial_id: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, trial_id: str, trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_path( + customer_id: str, feed_id: str, feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item string.""" + return "customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}".format( + customer_id=customer_id, feed_id=feed_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_path(path: str) -> Dict[str, str]: + """Parses a feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItems/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_path( + customer_id: str, feed_id: str, feed_item_set_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set string.""" + return "customers/{customer_id}/feedItemSets/{feed_id}~{feed_item_set_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + ) + + @staticmethod + def parse_feed_item_set_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_link_path( + customer_id: str, + feed_id: str, + feed_item_set_id: str, + feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set_link string.""" + return "customers/{customer_id}/feedItemSetLinks/{feed_id}~{feed_item_set_id}~{feed_item_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_set_link_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSetLinks/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_target_path( + customer_id: str, + feed_id: str, + feed_item_id: str, + feed_item_target_type: str, + feed_item_target_id: str, + ) -> str: + """Returns a fully-qualified feed_item_target string.""" + return "customers/{customer_id}/feedItemTargets/{feed_id}~{feed_item_id}~{feed_item_target_type}~{feed_item_target_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_id=feed_item_id, + feed_item_target_type=feed_item_target_type, + feed_item_target_id=feed_item_target_id, + ) + + @staticmethod + def parse_feed_item_target_path(path: str) -> Dict[str, str]: + """Parses a feed_item_target path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemTargets/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_mapping_path( + customer_id: str, feed_id: str, feed_mapping_id: str, + ) -> str: + """Returns a fully-qualified feed_mapping string.""" + return "customers/{customer_id}/feedMappings/{feed_id}~{feed_mapping_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_mapping_id=feed_mapping_id, + ) + + @staticmethod + def parse_feed_mapping_path(path: str) -> Dict[str, str]: + """Parses a feed_mapping path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedMappings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path(customer_id: str, keyword_plan_id: str,) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def media_file_path(customer_id: str, media_file_id: str,) -> str: + """Returns a fully-qualified media_file string.""" + return "customers/{customer_id}/mediaFiles/{media_file_id}".format( + customer_id=customer_id, media_file_id=media_file_id, + ) + + @staticmethod + def parse_media_file_path(path: str) -> Dict[str, str]: + """Parses a media_file path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/mediaFiles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def remarketing_action_path( + customer_id: str, remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_criterion_path( + customer_id: str, shared_set_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path(customer_id: str, shared_set_id: str,) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path(customer_id: str, user_interest_id: str,) -> str: + """Returns a fully-qualified user_interest string.""" + return "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, user_interest_id=user_interest_id, + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path(customer_id: str, user_list_id: str,) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, BatchJobServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the batch job service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, BatchJobServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, BatchJobServiceTransport): + # transport is a BatchJobServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_batch_job( + self, + request: Union[batch_job_service.MutateBatchJobRequest, dict] = None, + *, + customer_id: str = None, + operation: batch_job_service.BatchJobOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> batch_job_service.MutateBatchJobResponse: + r"""Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateBatchJobRequest, dict]): + The request object. Request message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v12.services.BatchJobService.MutateBatchJob]. + customer_id (str): + Required. The ID of the customer for + which to create a batch job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.BatchJobOperation): + Required. The operation to perform on + an individual batch job. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateBatchJobResponse: + Response message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v12.services.BatchJobService.MutateBatchJob]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a batch_job_service.MutateBatchJobRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, batch_job_service.MutateBatchJobRequest): + request = batch_job_service.MutateBatchJobRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_batch_job] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_batch_job_results( + self, + request: Union[ + batch_job_service.ListBatchJobResultsRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListBatchJobResultsPager: + r"""Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListBatchJobResultsRequest, dict]): + The request object. Request message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v12.services.BatchJobService.ListBatchJobResults]. + resource_name (str): + Required. The resource name of the + batch job whose results are being + listed. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.batch_job_service.pagers.ListBatchJobResultsPager: + Response message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v12.services.BatchJobService.ListBatchJobResults]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a batch_job_service.ListBatchJobResultsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, batch_job_service.ListBatchJobResultsRequest + ): + request = batch_job_service.ListBatchJobResultsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_batch_job_results + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListBatchJobResultsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def run_batch_job( + self, + request: Union[batch_job_service.RunBatchJobRequest, dict] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.RunBatchJobRequest, dict]): + The request object. Request message for + [BatchJobService.RunBatchJob][google.ads.googleads.v12.services.BatchJobService.RunBatchJob]. + resource_name (str): + Required. The resource name of the + BatchJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a batch_job_service.RunBatchJobRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, batch_job_service.RunBatchJobRequest): + request = batch_job_service.RunBatchJobRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.run_batch_job] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=batch_job.BatchJob.BatchJobMetadata, + ) + + # Done; return the response. + return response + + def add_batch_job_operations( + self, + request: Union[ + batch_job_service.AddBatchJobOperationsRequest, dict + ] = None, + *, + resource_name: str = None, + sequence_token: str = None, + mutate_operations: Sequence[google_ads_service.MutateOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> batch_job_service.AddBatchJobOperationsResponse: + r"""Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.AddBatchJobOperationsRequest, dict]): + The request object. Request message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v12.services.BatchJobService.AddBatchJobOperations]. + resource_name (str): + Required. The resource name of the + batch job. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + sequence_token (str): + A token used to enforce sequencing. + + The first AddBatchJobOperations request for a batch job + should not set sequence_token. Subsequent requests must + set sequence_token to the value of next_sequence_token + received in the previous AddBatchJobOperations response. + + This corresponds to the ``sequence_token`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (Sequence[google.ads.googleads.v12.services.types.MutateOperation]): + Required. The list of mutates being + added. + Operations can use negative integers as + temp ids to signify dependencies between + entities created in this batch job. For + example, a customer with id = 1234 can + create a campaign and an ad group in + that same campaign by creating a + campaign in the first operation with the + resource name explicitly set to + "customers/1234/campaigns/-1", and + creating an ad group in the second + operation with the campaign field also + set to "customers/1234/campaigns/-1". + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.AddBatchJobOperationsResponse: + Response message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v12.services.BatchJobService.AddBatchJobOperations]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [resource_name, sequence_token, mutate_operations] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a batch_job_service.AddBatchJobOperationsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, batch_job_service.AddBatchJobOperationsRequest + ): + request = batch_job_service.AddBatchJobOperationsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if sequence_token is not None: + request.sequence_token = sequence_token + if mutate_operations is not None: + request.mutate_operations = mutate_operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.add_batch_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("BatchJobServiceClient",) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/pagers.py b/google/ads/googleads/v12/services/services/batch_job_service/pagers.py new file mode 100644 index 000000000..c53470797 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/pagers.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.services.types import batch_job_service + + +class ListBatchJobResultsPager: + """A pager for iterating through ``list_batch_job_results`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.ListBatchJobResultsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListBatchJobResults`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.ListBatchJobResultsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., batch_job_service.ListBatchJobResultsResponse], + request: batch_job_service.ListBatchJobResultsRequest, + response: batch_job_service.ListBatchJobResultsResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.ListBatchJobResultsRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.ListBatchJobResultsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = batch_job_service.ListBatchJobResultsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[batch_job_service.ListBatchJobResultsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__(self) -> Iterator[batch_job_service.BatchJobResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/transports/__init__.py b/google/ads/googleads/v12/services/services/batch_job_service/transports/__init__.py new file mode 100644 index 000000000..91c165c36 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 BatchJobServiceTransport +from .grpc import BatchJobServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BatchJobServiceTransport]] +_transport_registry["grpc"] = BatchJobServiceGrpcTransport + +__all__ = ( + "BatchJobServiceTransport", + "BatchJobServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/transports/base.py b/google/ads/googleads/v12/services/services/batch_job_service/transports/base.py new file mode 100644 index 000000000..00f9fe692 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/transports/base.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import batch_job_service +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class BatchJobServiceTransport(abc.ABC): + """Abstract transport class for BatchJobService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_batch_job: gapic_v1.method.wrap_method( + self.mutate_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.list_batch_job_results: gapic_v1.method.wrap_method( + self.list_batch_job_results, + default_timeout=None, + client_info=client_info, + ), + self.run_batch_job: gapic_v1.method.wrap_method( + self.run_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.add_batch_job_operations: gapic_v1.method.wrap_method( + self.add_batch_job_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_batch_job( + self, + ) -> Callable[ + [batch_job_service.MutateBatchJobRequest], + Union[ + batch_job_service.MutateBatchJobResponse, + Awaitable[batch_job_service.MutateBatchJobResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_batch_job_results( + self, + ) -> Callable[ + [batch_job_service.ListBatchJobResultsRequest], + Union[ + batch_job_service.ListBatchJobResultsResponse, + Awaitable[batch_job_service.ListBatchJobResultsResponse], + ], + ]: + raise NotImplementedError() + + @property + def run_batch_job( + self, + ) -> Callable[ + [batch_job_service.RunBatchJobRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def add_batch_job_operations( + self, + ) -> Callable[ + [batch_job_service.AddBatchJobOperationsRequest], + Union[ + batch_job_service.AddBatchJobOperationsResponse, + Awaitable[batch_job_service.AddBatchJobOperationsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("BatchJobServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/batch_job_service/transports/grpc.py b/google/ads/googleads/v12/services/services/batch_job_service/transports/grpc.py new file mode 100644 index 000000000..a559df976 --- /dev/null +++ b/google/ads/googleads/v12/services/services/batch_job_service/transports/grpc.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import batch_job_service +from google.longrunning import operations_pb2 # type: ignore +from .base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO + + +class BatchJobServiceGrpcTransport(BatchJobServiceTransport): + """gRPC backend transport for BatchJobService. + + Service to manage batch jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: 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 channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_batch_job( + self, + ) -> Callable[ + [batch_job_service.MutateBatchJobRequest], + batch_job_service.MutateBatchJobResponse, + ]: + r"""Return a callable for the mutate batch job method over gRPC. + + Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateBatchJobRequest], + ~.MutateBatchJobResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_batch_job" not in self._stubs: + self._stubs["mutate_batch_job"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BatchJobService/MutateBatchJob", + request_serializer=batch_job_service.MutateBatchJobRequest.serialize, + response_deserializer=batch_job_service.MutateBatchJobResponse.deserialize, + ) + return self._stubs["mutate_batch_job"] + + @property + def list_batch_job_results( + self, + ) -> Callable[ + [batch_job_service.ListBatchJobResultsRequest], + batch_job_service.ListBatchJobResultsResponse, + ]: + r"""Return a callable for the list batch job results method over gRPC. + + Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListBatchJobResultsRequest], + ~.ListBatchJobResultsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_batch_job_results" not in self._stubs: + self._stubs[ + "list_batch_job_results" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BatchJobService/ListBatchJobResults", + request_serializer=batch_job_service.ListBatchJobResultsRequest.serialize, + response_deserializer=batch_job_service.ListBatchJobResultsResponse.deserialize, + ) + return self._stubs["list_batch_job_results"] + + @property + def run_batch_job( + self, + ) -> Callable[ + [batch_job_service.RunBatchJobRequest], operations_pb2.Operation + ]: + r"""Return a callable for the run batch job method over gRPC. + + Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunBatchJobRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_batch_job" not in self._stubs: + self._stubs["run_batch_job"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BatchJobService/RunBatchJob", + request_serializer=batch_job_service.RunBatchJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["run_batch_job"] + + @property + def add_batch_job_operations( + self, + ) -> Callable[ + [batch_job_service.AddBatchJobOperationsRequest], + batch_job_service.AddBatchJobOperationsResponse, + ]: + r"""Return a callable for the add batch job operations method over gRPC. + + Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.AddBatchJobOperationsRequest], + ~.AddBatchJobOperationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_batch_job_operations" not in self._stubs: + self._stubs[ + "add_batch_job_operations" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BatchJobService/AddBatchJobOperations", + request_serializer=batch_job_service.AddBatchJobOperationsRequest.serialize, + response_deserializer=batch_job_service.AddBatchJobOperationsResponse.deserialize, + ) + return self._stubs["add_batch_job_operations"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("BatchJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/__init__.py b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/__init__.py new file mode 100644 index 000000000..722a42c20 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BiddingDataExclusionServiceClient + +__all__ = ("BiddingDataExclusionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/client.py b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/client.py new file mode 100644 index 000000000..91694f6af --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/client.py @@ -0,0 +1,514 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_data_exclusion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingDataExclusionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingDataExclusionServiceGrpcTransport + + +class BiddingDataExclusionServiceClientMeta(type): + """Metaclass for the BiddingDataExclusionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingDataExclusionServiceTransport]] + _transport_registry["grpc"] = BiddingDataExclusionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[BiddingDataExclusionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingDataExclusionServiceClient( + metaclass=BiddingDataExclusionServiceClientMeta +): + """Service to manage bidding data exclusions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingDataExclusionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingDataExclusionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, BiddingDataExclusionServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding data exclusion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, BiddingDataExclusionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, BiddingDataExclusionServiceTransport): + # transport is a BiddingDataExclusionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_bidding_data_exclusions( + self, + request: Union[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + bidding_data_exclusion_service.BiddingDataExclusionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse: + r"""Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateBiddingDataExclusionsRequest, dict]): + The request object. Request message for + [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v12.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. + customer_id (str): + Required. ID of the customer whose + data exclusions are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingDataExclusionOperation]): + Required. The list of operations to + perform on individual data exclusions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateBiddingDataExclusionsResponse: + Response message for data exlusions + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + ): + request = bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_data_exclusions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("BiddingDataExclusionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/__init__.py b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/__init__.py new file mode 100644 index 000000000..49c58c30e --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 BiddingDataExclusionServiceTransport +from .grpc import BiddingDataExclusionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BiddingDataExclusionServiceTransport]] +_transport_registry["grpc"] = BiddingDataExclusionServiceGrpcTransport + +__all__ = ( + "BiddingDataExclusionServiceTransport", + "BiddingDataExclusionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/base.py b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/base.py new file mode 100644 index 000000000..1dbecf873 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_data_exclusion_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class BiddingDataExclusionServiceTransport(abc.ABC): + """Abstract transport class for BiddingDataExclusionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_data_exclusions: gapic_v1.method.wrap_method( + self.mutate_bidding_data_exclusions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_data_exclusions( + self, + ) -> Callable[ + [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], + Union[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, + Awaitable[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("BiddingDataExclusionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/grpc.py b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/grpc.py new file mode 100644 index 000000000..2f8a6a3c3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_data_exclusion_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_data_exclusion_service, +) +from .base import BiddingDataExclusionServiceTransport, DEFAULT_CLIENT_INFO + + +class BiddingDataExclusionServiceGrpcTransport( + BiddingDataExclusionServiceTransport +): + """gRPC backend transport for BiddingDataExclusionService. + + Service to manage bidding data exclusions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_bidding_data_exclusions( + self, + ) -> Callable[ + [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, + ]: + r"""Return a callable for the mutate bidding data exclusions method over gRPC. + + Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingDataExclusionsRequest], + ~.MutateBiddingDataExclusionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_data_exclusions" not in self._stubs: + self._stubs[ + "mutate_bidding_data_exclusions" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BiddingDataExclusionService/MutateBiddingDataExclusions", + request_serializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest.serialize, + response_deserializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse.deserialize, + ) + return self._stubs["mutate_bidding_data_exclusions"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("BiddingDataExclusionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/__init__.py b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/__init__.py new file mode 100644 index 000000000..591ac250c --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BiddingSeasonalityAdjustmentServiceClient + +__all__ = ("BiddingSeasonalityAdjustmentServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/client.py b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/client.py new file mode 100644 index 000000000..ab82255fd --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/client.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_seasonality_adjustment_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingSeasonalityAdjustmentServiceGrpcTransport + + +class BiddingSeasonalityAdjustmentServiceClientMeta(type): + """Metaclass for the BiddingSeasonalityAdjustmentService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingSeasonalityAdjustmentServiceTransport]] + _transport_registry[ + "grpc" + ] = BiddingSeasonalityAdjustmentServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[BiddingSeasonalityAdjustmentServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingSeasonalityAdjustmentServiceClient( + metaclass=BiddingSeasonalityAdjustmentServiceClientMeta +): + """Service to manage bidding seasonality adjustments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingSeasonalityAdjustmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingSeasonalityAdjustmentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, BiddingSeasonalityAdjustmentServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding seasonality adjustment service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, BiddingSeasonalityAdjustmentServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, BiddingSeasonalityAdjustmentServiceTransport): + # transport is a BiddingSeasonalityAdjustmentServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_bidding_seasonality_adjustments( + self, + request: Union[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse: + r"""Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateBiddingSeasonalityAdjustmentsRequest, dict]): + The request object. Request message for + [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v12.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. + customer_id (str): + Required. ID of the customer whose + seasonality adjustments are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingSeasonalityAdjustmentOperation]): + Required. The list of operations to + perform on individual seasonality + adjustments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateBiddingSeasonalityAdjustmentsResponse: + Response message for seasonality + adjustments mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + ): + request = bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_seasonality_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("BiddingSeasonalityAdjustmentServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/__init__.py b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/__init__.py new file mode 100644 index 000000000..e65c9aea5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 BiddingSeasonalityAdjustmentServiceTransport +from .grpc import BiddingSeasonalityAdjustmentServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BiddingSeasonalityAdjustmentServiceTransport]] +_transport_registry["grpc"] = BiddingSeasonalityAdjustmentServiceGrpcTransport + +__all__ = ( + "BiddingSeasonalityAdjustmentServiceTransport", + "BiddingSeasonalityAdjustmentServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/base.py b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/base.py new file mode 100644 index 000000000..1f19020b6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_seasonality_adjustment_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class BiddingSeasonalityAdjustmentServiceTransport(abc.ABC): + """Abstract transport class for BiddingSeasonalityAdjustmentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_seasonality_adjustments: gapic_v1.method.wrap_method( + self.mutate_bidding_seasonality_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_seasonality_adjustments( + self, + ) -> Callable[ + [ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest + ], + Union[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, + Awaitable[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("BiddingSeasonalityAdjustmentServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/grpc.py b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/grpc.py new file mode 100644 index 000000000..53c19db72 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_seasonality_adjustment_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + bidding_seasonality_adjustment_service, +) +from .base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class BiddingSeasonalityAdjustmentServiceGrpcTransport( + BiddingSeasonalityAdjustmentServiceTransport +): + """gRPC backend transport for BiddingSeasonalityAdjustmentService. + + Service to manage bidding seasonality adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_bidding_seasonality_adjustments( + self, + ) -> Callable[ + [ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest + ], + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, + ]: + r"""Return a callable for the mutate bidding seasonality + adjustments method over gRPC. + + Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingSeasonalityAdjustmentsRequest], + ~.MutateBiddingSeasonalityAdjustmentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_seasonality_adjustments" not in self._stubs: + self._stubs[ + "mutate_bidding_seasonality_adjustments" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BiddingSeasonalityAdjustmentService/MutateBiddingSeasonalityAdjustments", + request_serializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest.serialize, + response_deserializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse.deserialize, + ) + return self._stubs["mutate_bidding_seasonality_adjustments"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("BiddingSeasonalityAdjustmentServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_strategy_service/__init__.py b/google/ads/googleads/v12/services/services/bidding_strategy_service/__init__.py new file mode 100644 index 000000000..e307b871e --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_strategy_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BiddingStrategyServiceClient + +__all__ = ("BiddingStrategyServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_strategy_service/client.py b/google/ads/googleads/v12/services/services/bidding_strategy_service/client.py new file mode 100644 index 000000000..641a84e9a --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_strategy_service/client.py @@ -0,0 +1,505 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import bidding_strategy_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingStrategyServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingStrategyServiceGrpcTransport + + +class BiddingStrategyServiceClientMeta(type): + """Metaclass for the BiddingStrategyService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingStrategyServiceTransport]] + _transport_registry["grpc"] = BiddingStrategyServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[BiddingStrategyServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingStrategyServiceClient(metaclass=BiddingStrategyServiceClientMeta): + """Service to manage bidding strategies.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingStrategyServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingStrategyServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, BiddingStrategyServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding strategy service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, BiddingStrategyServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, BiddingStrategyServiceTransport): + # transport is a BiddingStrategyServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_bidding_strategies( + self, + request: Union[ + bidding_strategy_service.MutateBiddingStrategiesRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + bidding_strategy_service.BiddingStrategyOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bidding_strategy_service.MutateBiddingStrategiesResponse: + r"""Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateBiddingStrategiesRequest, dict]): + The request object. Request message for + [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v12.services.BiddingStrategyService.MutateBiddingStrategies]. + customer_id (str): + Required. The ID of the customer + whose bidding strategies are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingStrategyOperation]): + Required. The list of operations to + perform on individual bidding + strategies. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateBiddingStrategiesResponse: + Response message for bidding strategy + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a bidding_strategy_service.MutateBiddingStrategiesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, bidding_strategy_service.MutateBiddingStrategiesRequest + ): + request = bidding_strategy_service.MutateBiddingStrategiesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_strategies + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("BiddingStrategyServiceClient",) diff --git a/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/__init__.py b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/__init__.py new file mode 100644 index 000000000..80d3172dc --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 BiddingStrategyServiceTransport +from .grpc import BiddingStrategyServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BiddingStrategyServiceTransport]] +_transport_registry["grpc"] = BiddingStrategyServiceGrpcTransport + +__all__ = ( + "BiddingStrategyServiceTransport", + "BiddingStrategyServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/base.py b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/base.py new file mode 100644 index 000000000..ea167eedb --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import bidding_strategy_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class BiddingStrategyServiceTransport(abc.ABC): + """Abstract transport class for BiddingStrategyService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_strategies: gapic_v1.method.wrap_method( + self.mutate_bidding_strategies, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_strategies( + self, + ) -> Callable[ + [bidding_strategy_service.MutateBiddingStrategiesRequest], + Union[ + bidding_strategy_service.MutateBiddingStrategiesResponse, + Awaitable[bidding_strategy_service.MutateBiddingStrategiesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("BiddingStrategyServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/grpc.py b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/grpc.py new file mode 100644 index 000000000..8d6ac3605 --- /dev/null +++ b/google/ads/googleads/v12/services/services/bidding_strategy_service/transports/grpc.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import bidding_strategy_service +from .base import BiddingStrategyServiceTransport, DEFAULT_CLIENT_INFO + + +class BiddingStrategyServiceGrpcTransport(BiddingStrategyServiceTransport): + """gRPC backend transport for BiddingStrategyService. + + Service to manage bidding strategies. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_bidding_strategies( + self, + ) -> Callable[ + [bidding_strategy_service.MutateBiddingStrategiesRequest], + bidding_strategy_service.MutateBiddingStrategiesResponse, + ]: + r"""Return a callable for the mutate bidding strategies method over gRPC. + + Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateBiddingStrategiesRequest], + ~.MutateBiddingStrategiesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_strategies" not in self._stubs: + self._stubs[ + "mutate_bidding_strategies" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BiddingStrategyService/MutateBiddingStrategies", + request_serializer=bidding_strategy_service.MutateBiddingStrategiesRequest.serialize, + response_deserializer=bidding_strategy_service.MutateBiddingStrategiesResponse.deserialize, + ) + return self._stubs["mutate_bidding_strategies"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("BiddingStrategyServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/billing_setup_service/__init__.py b/google/ads/googleads/v12/services/services/billing_setup_service/__init__.py new file mode 100644 index 000000000..72bd54edb --- /dev/null +++ b/google/ads/googleads/v12/services/services/billing_setup_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BillingSetupServiceClient + +__all__ = ("BillingSetupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/billing_setup_service/client.py b/google/ads/googleads/v12/services/services/billing_setup_service/client.py new file mode 100644 index 000000000..fb66ddc13 --- /dev/null +++ b/google/ads/googleads/v12/services/services/billing_setup_service/client.py @@ -0,0 +1,511 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import billing_setup_service +from .transports.base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import BillingSetupServiceGrpcTransport + + +class BillingSetupServiceClientMeta(type): + """Metaclass for the BillingSetupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BillingSetupServiceTransport]] + _transport_registry["grpc"] = BillingSetupServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[BillingSetupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BillingSetupServiceClient(metaclass=BillingSetupServiceClientMeta): + """A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BillingSetupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BillingSetupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def billing_setup_path(customer_id: str, billing_setup_id: str,) -> str: + """Returns a fully-qualified billing_setup string.""" + return "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, billing_setup_id=billing_setup_id, + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, BillingSetupServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the billing setup service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, BillingSetupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, BillingSetupServiceTransport): + # transport is a BillingSetupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_billing_setup( + self, + request: Union[ + billing_setup_service.MutateBillingSetupRequest, dict + ] = None, + *, + customer_id: str = None, + operation: billing_setup_service.BillingSetupOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> billing_setup_service.MutateBillingSetupResponse: + r"""Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateBillingSetupRequest, dict]): + The request object. Request message for billing setup + mutate operations. + customer_id (str): + Required. Id of the customer to apply + the billing setup mutate operation to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.BillingSetupOperation): + Required. The operation to perform. + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateBillingSetupResponse: + Response message for a billing setup + operation. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a billing_setup_service.MutateBillingSetupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, billing_setup_service.MutateBillingSetupRequest + ): + request = billing_setup_service.MutateBillingSetupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_billing_setup + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("BillingSetupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/billing_setup_service/transports/__init__.py b/google/ads/googleads/v12/services/services/billing_setup_service/transports/__init__.py new file mode 100644 index 000000000..a83a122ba --- /dev/null +++ b/google/ads/googleads/v12/services/services/billing_setup_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 BillingSetupServiceTransport +from .grpc import BillingSetupServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BillingSetupServiceTransport]] +_transport_registry["grpc"] = BillingSetupServiceGrpcTransport + +__all__ = ( + "BillingSetupServiceTransport", + "BillingSetupServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/billing_setup_service/transports/base.py b/google/ads/googleads/v12/services/services/billing_setup_service/transports/base.py new file mode 100644 index 000000000..02ed50c43 --- /dev/null +++ b/google/ads/googleads/v12/services/services/billing_setup_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import billing_setup_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class BillingSetupServiceTransport(abc.ABC): + """Abstract transport class for BillingSetupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_billing_setup: gapic_v1.method.wrap_method( + self.mutate_billing_setup, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_billing_setup( + self, + ) -> Callable[ + [billing_setup_service.MutateBillingSetupRequest], + Union[ + billing_setup_service.MutateBillingSetupResponse, + Awaitable[billing_setup_service.MutateBillingSetupResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("BillingSetupServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/billing_setup_service/transports/grpc.py b/google/ads/googleads/v12/services/services/billing_setup_service/transports/grpc.py new file mode 100644 index 000000000..a121d0544 --- /dev/null +++ b/google/ads/googleads/v12/services/services/billing_setup_service/transports/grpc.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import billing_setup_service +from .base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO + + +class BillingSetupServiceGrpcTransport(BillingSetupServiceTransport): + """gRPC backend transport for BillingSetupService. + + A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_billing_setup( + self, + ) -> Callable[ + [billing_setup_service.MutateBillingSetupRequest], + billing_setup_service.MutateBillingSetupResponse, + ]: + r"""Return a callable for the mutate billing setup method over gRPC. + + Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateBillingSetupRequest], + ~.MutateBillingSetupResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_billing_setup" not in self._stubs: + self._stubs["mutate_billing_setup"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.BillingSetupService/MutateBillingSetup", + request_serializer=billing_setup_service.MutateBillingSetupRequest.serialize, + response_deserializer=billing_setup_service.MutateBillingSetupResponse.deserialize, + ) + return self._stubs["mutate_billing_setup"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("BillingSetupServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_asset_service/__init__.py new file mode 100644 index 000000000..8dfbd960f --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignAssetServiceClient + +__all__ = ("CampaignAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_service/client.py b/google/ads/googleads/v12/services/services/campaign_asset_service/client.py new file mode 100644 index 000000000..9eede0de4 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_service/client.py @@ -0,0 +1,528 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignAssetServiceGrpcTransport + + +class CampaignAssetServiceClientMeta(type): + """Metaclass for the CampaignAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignAssetServiceTransport]] + _transport_registry["grpc"] = CampaignAssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignAssetServiceClient(metaclass=CampaignAssetServiceClientMeta): + """Service to manage campaign assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, campaign_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignAssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignAssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignAssetServiceTransport): + # transport is a CampaignAssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_assets( + self, + request: Union[ + campaign_asset_service.MutateCampaignAssetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_asset_service.CampaignAssetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_asset_service.MutateCampaignAssetsResponse: + r"""Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignAssetsRequest, dict]): + The request object. Request message for + [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v12.services.CampaignAssetService.MutateCampaignAssets]. + customer_id (str): + Required. The ID of the customer + whose campaign assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignAssetOperation]): + Required. The list of operations to + perform on individual campaign assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignAssetsResponse: + Response message for a campaign asset + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_asset_service.MutateCampaignAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_asset_service.MutateCampaignAssetsRequest + ): + request = campaign_asset_service.MutateCampaignAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/__init__.py new file mode 100644 index 000000000..1b13f47a4 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignAssetServiceTransport +from .grpc import CampaignAssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignAssetServiceTransport]] +_transport_registry["grpc"] = CampaignAssetServiceGrpcTransport + +__all__ = ( + "CampaignAssetServiceTransport", + "CampaignAssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/base.py new file mode 100644 index 000000000..c9862220e --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignAssetServiceTransport(abc.ABC): + """Abstract transport class for CampaignAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_assets: gapic_v1.method.wrap_method( + self.mutate_campaign_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_assets( + self, + ) -> Callable[ + [campaign_asset_service.MutateCampaignAssetsRequest], + Union[ + campaign_asset_service.MutateCampaignAssetsResponse, + Awaitable[campaign_asset_service.MutateCampaignAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignAssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/grpc.py new file mode 100644 index 000000000..13ee792fb --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_service/transports/grpc.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_service +from .base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignAssetServiceGrpcTransport(CampaignAssetServiceTransport): + """gRPC backend transport for CampaignAssetService. + + Service to manage campaign assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_assets( + self, + ) -> Callable[ + [campaign_asset_service.MutateCampaignAssetsRequest], + campaign_asset_service.MutateCampaignAssetsResponse, + ]: + r"""Return a callable for the mutate campaign assets method over gRPC. + + Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignAssetsRequest], + ~.MutateCampaignAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_assets" not in self._stubs: + self._stubs[ + "mutate_campaign_assets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignAssetService/MutateCampaignAssets", + request_serializer=campaign_asset_service.MutateCampaignAssetsRequest.serialize, + response_deserializer=campaign_asset_service.MutateCampaignAssetsResponse.deserialize, + ) + return self._stubs["mutate_campaign_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_set_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_asset_set_service/__init__.py new file mode 100644 index 000000000..c96c3300d --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignAssetSetServiceClient + +__all__ = ("CampaignAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_set_service/client.py b/google/ads/googleads/v12/services/services/campaign_asset_set_service/client.py new file mode 100644 index 000000000..33adaa695 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_set_service/client.py @@ -0,0 +1,528 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignAssetSetServiceGrpcTransport + + +class CampaignAssetSetServiceClientMeta(type): + """Metaclass for the CampaignAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignAssetSetServiceTransport]] + _transport_registry["grpc"] = CampaignAssetSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignAssetSetServiceClient( + metaclass=CampaignAssetSetServiceClientMeta +): + """Service to manage campaign asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, campaign_id: str, asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignAssetSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignAssetSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignAssetSetServiceTransport): + # transport is a CampaignAssetSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_asset_sets( + self, + request: Union[ + campaign_asset_set_service.MutateCampaignAssetSetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_asset_set_service.CampaignAssetSetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_asset_set_service.MutateCampaignAssetSetsResponse: + r"""Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignAssetSetsRequest, dict]): + The request object. Request message for + [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v12.services.CampaignAssetSetService.MutateCampaignAssetSets]. + customer_id (str): + Required. The ID of the customer + whose campaign asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignAssetSetOperation]): + Required. The list of operations to + perform on individual campaign asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignAssetSetsResponse: + Response message for a campaign asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_asset_set_service.MutateCampaignAssetSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_asset_set_service.MutateCampaignAssetSetsRequest + ): + request = campaign_asset_set_service.MutateCampaignAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/__init__.py new file mode 100644 index 000000000..255fa2891 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignAssetSetServiceTransport +from .grpc import CampaignAssetSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignAssetSetServiceTransport]] +_transport_registry["grpc"] = CampaignAssetSetServiceGrpcTransport + +__all__ = ( + "CampaignAssetSetServiceTransport", + "CampaignAssetSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/base.py new file mode 100644 index 000000000..19c01449b --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignAssetSetServiceTransport(abc.ABC): + """Abstract transport class for CampaignAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_asset_sets: gapic_v1.method.wrap_method( + self.mutate_campaign_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_asset_sets( + self, + ) -> Callable[ + [campaign_asset_set_service.MutateCampaignAssetSetsRequest], + Union[ + campaign_asset_set_service.MutateCampaignAssetSetsResponse, + Awaitable[ + campaign_asset_set_service.MutateCampaignAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignAssetSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..d291e502d --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_asset_set_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_asset_set_service +from .base import CampaignAssetSetServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignAssetSetServiceGrpcTransport(CampaignAssetSetServiceTransport): + """gRPC backend transport for CampaignAssetSetService. + + Service to manage campaign asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_asset_sets( + self, + ) -> Callable[ + [campaign_asset_set_service.MutateCampaignAssetSetsRequest], + campaign_asset_set_service.MutateCampaignAssetSetsResponse, + ]: + r"""Return a callable for the mutate campaign asset sets method over gRPC. + + Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignAssetSetsRequest], + ~.MutateCampaignAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_asset_sets" not in self._stubs: + self._stubs[ + "mutate_campaign_asset_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignAssetSetService/MutateCampaignAssetSets", + request_serializer=campaign_asset_set_service.MutateCampaignAssetSetsRequest.serialize, + response_deserializer=campaign_asset_set_service.MutateCampaignAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_campaign_asset_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/__init__.py new file mode 100644 index 000000000..32e03a072 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignBidModifierServiceClient + +__all__ = ("CampaignBidModifierServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/client.py b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/client.py new file mode 100644 index 000000000..0614667df --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/client.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignBidModifierServiceGrpcTransport + + +class CampaignBidModifierServiceClientMeta(type): + """Metaclass for the CampaignBidModifierService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignBidModifierServiceTransport]] + _transport_registry["grpc"] = CampaignBidModifierServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignBidModifierServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignBidModifierServiceClient( + metaclass=CampaignBidModifierServiceClientMeta +): + """Service to manage campaign bid modifiers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBidModifierServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignBidModifierServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign bid modifier service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignBidModifierServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignBidModifierServiceTransport): + # transport is a CampaignBidModifierServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_bid_modifiers( + self, + request: Union[ + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_bid_modifier_service.CampaignBidModifierOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_bid_modifier_service.MutateCampaignBidModifiersResponse: + r"""Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignBidModifiersRequest, dict]): + The request object. Request message for + [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v12.services.CampaignBidModifierService.MutateCampaignBidModifiers]. + customer_id (str): + Required. ID of the customer whose + campaign bid modifiers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignBidModifierOperation]): + Required. The list of operations to + perform on individual campaign bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignBidModifiersResponse: + Response message for campaign bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_bid_modifier_service.MutateCampaignBidModifiersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + ): + request = campaign_bid_modifier_service.MutateCampaignBidModifiersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignBidModifierServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/__init__.py new file mode 100644 index 000000000..6b1f3c2c2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignBidModifierServiceTransport +from .grpc import CampaignBidModifierServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignBidModifierServiceTransport]] +_transport_registry["grpc"] = CampaignBidModifierServiceGrpcTransport + +__all__ = ( + "CampaignBidModifierServiceTransport", + "CampaignBidModifierServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/base.py new file mode 100644 index 000000000..bfbf717df --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_bid_modifier_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignBidModifierServiceTransport(abc.ABC): + """Abstract transport class for CampaignBidModifierService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_bid_modifiers: gapic_v1.method.wrap_method( + self.mutate_campaign_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_bid_modifiers( + self, + ) -> Callable[ + [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], + Union[ + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, + Awaitable[ + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignBidModifierServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/grpc.py new file mode 100644 index 000000000..ed300e458 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_bid_modifier_service/transports/grpc.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_bid_modifier_service, +) +from .base import CampaignBidModifierServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignBidModifierServiceGrpcTransport( + CampaignBidModifierServiceTransport +): + """gRPC backend transport for CampaignBidModifierService. + + Service to manage campaign bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_bid_modifiers( + self, + ) -> Callable[ + [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, + ]: + r"""Return a callable for the mutate campaign bid modifiers method over gRPC. + + Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBidModifiersRequest], + ~.MutateCampaignBidModifiersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_bid_modifiers" not in self._stubs: + self._stubs[ + "mutate_campaign_bid_modifiers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignBidModifierService/MutateCampaignBidModifiers", + request_serializer=campaign_bid_modifier_service.MutateCampaignBidModifiersRequest.serialize, + response_deserializer=campaign_bid_modifier_service.MutateCampaignBidModifiersResponse.deserialize, + ) + return self._stubs["mutate_campaign_bid_modifiers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_budget_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_budget_service/__init__.py new file mode 100644 index 000000000..dc744cac0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_budget_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignBudgetServiceClient + +__all__ = ("CampaignBudgetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_budget_service/client.py b/google/ads/googleads/v12/services/services/campaign_budget_service/client.py new file mode 100644 index 000000000..55d52bfd5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_budget_service/client.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_budget_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignBudgetServiceGrpcTransport + + +class CampaignBudgetServiceClientMeta(type): + """Metaclass for the CampaignBudgetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignBudgetServiceTransport]] + _transport_registry["grpc"] = CampaignBudgetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignBudgetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignBudgetServiceClient(metaclass=CampaignBudgetServiceClientMeta): + """Service to manage campaign budgets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignBudgetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBudgetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_budget_path(customer_id: str, campaign_budget_id: str,) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignBudgetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign budget service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignBudgetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignBudgetServiceTransport): + # transport is a CampaignBudgetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_budgets( + self, + request: Union[ + campaign_budget_service.MutateCampaignBudgetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_budget_service.CampaignBudgetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_budget_service.MutateCampaignBudgetsResponse: + r"""Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignBudgetsRequest, dict]): + The request object. Request message for + [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v12.services.CampaignBudgetService.MutateCampaignBudgets]. + customer_id (str): + Required. The ID of the customer + whose campaign budgets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignBudgetOperation]): + Required. The list of operations to + perform on individual campaign budgets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignBudgetsResponse: + Response message for campaign budget + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_budget_service.MutateCampaignBudgetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_budget_service.MutateCampaignBudgetsRequest + ): + request = campaign_budget_service.MutateCampaignBudgetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_budgets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignBudgetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_budget_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/__init__.py new file mode 100644 index 000000000..329bef917 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignBudgetServiceTransport +from .grpc import CampaignBudgetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignBudgetServiceTransport]] +_transport_registry["grpc"] = CampaignBudgetServiceGrpcTransport + +__all__ = ( + "CampaignBudgetServiceTransport", + "CampaignBudgetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_budget_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/base.py new file mode 100644 index 000000000..1b4ef76f3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_budget_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignBudgetServiceTransport(abc.ABC): + """Abstract transport class for CampaignBudgetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_budgets: gapic_v1.method.wrap_method( + self.mutate_campaign_budgets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_budgets( + self, + ) -> Callable[ + [campaign_budget_service.MutateCampaignBudgetsRequest], + Union[ + campaign_budget_service.MutateCampaignBudgetsResponse, + Awaitable[campaign_budget_service.MutateCampaignBudgetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignBudgetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_budget_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/grpc.py new file mode 100644 index 000000000..e4d35ae53 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_budget_service/transports/grpc.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_budget_service +from .base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignBudgetServiceGrpcTransport(CampaignBudgetServiceTransport): + """gRPC backend transport for CampaignBudgetService. + + Service to manage campaign budgets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_budgets( + self, + ) -> Callable[ + [campaign_budget_service.MutateCampaignBudgetsRequest], + campaign_budget_service.MutateCampaignBudgetsResponse, + ]: + r"""Return a callable for the mutate campaign budgets method over gRPC. + + Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBudgetsRequest], + ~.MutateCampaignBudgetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_budgets" not in self._stubs: + self._stubs[ + "mutate_campaign_budgets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignBudgetService/MutateCampaignBudgets", + request_serializer=campaign_budget_service.MutateCampaignBudgetsRequest.serialize, + response_deserializer=campaign_budget_service.MutateCampaignBudgetsResponse.deserialize, + ) + return self._stubs["mutate_campaign_budgets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignBudgetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/__init__.py new file mode 100644 index 000000000..d7ec20d29 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignConversionGoalServiceClient + +__all__ = ("CampaignConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/client.py b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/client.py new file mode 100644 index 000000000..68beda01a --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/client.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_conversion_goal_service, +) +from .transports.base import ( + CampaignConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignConversionGoalServiceGrpcTransport + + +class CampaignConversionGoalServiceClientMeta(type): + """Metaclass for the CampaignConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignConversionGoalServiceTransport]] + _transport_registry["grpc"] = CampaignConversionGoalServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignConversionGoalServiceClient( + metaclass=CampaignConversionGoalServiceClientMeta +): + """Service to manage campaign conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, campaign_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CampaignConversionGoalServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignConversionGoalServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignConversionGoalServiceTransport): + # transport is a CampaignConversionGoalServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_conversion_goals( + self, + request: Union[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_conversion_goal_service.CampaignConversionGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse: + r"""Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignConversionGoalsRequest, dict]): + The request object. Request message for + [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v12.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose campaign conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignConversionGoalOperation]): + Required. The list of operations to + perform on individual campaign + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignConversionGoalsResponse: + Response message for a campaign + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + ): + request = campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/__init__.py new file mode 100644 index 000000000..28cc7f6b7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignConversionGoalServiceTransport +from .grpc import CampaignConversionGoalServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignConversionGoalServiceTransport]] +_transport_registry["grpc"] = CampaignConversionGoalServiceGrpcTransport + +__all__ = ( + "CampaignConversionGoalServiceTransport", + "CampaignConversionGoalServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..814a37ad6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_conversion_goal_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CampaignConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_campaign_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_conversion_goals( + self, + ) -> Callable[ + [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], + Union[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, + Awaitable[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..4c964b815 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_conversion_goal_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_conversion_goal_service, +) +from .base import CampaignConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignConversionGoalServiceGrpcTransport( + CampaignConversionGoalServiceTransport +): + """gRPC backend transport for CampaignConversionGoalService. + + Service to manage campaign conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_conversion_goals( + self, + ) -> Callable[ + [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, + ]: + r"""Return a callable for the mutate campaign conversion + goals method over gRPC. + + Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignConversionGoalsRequest], + ~.MutateCampaignConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_conversion_goals" not in self._stubs: + self._stubs[ + "mutate_campaign_conversion_goals" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignConversionGoalService/MutateCampaignConversionGoals", + request_serializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest.serialize, + response_deserializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse.deserialize, + ) + return self._stubs["mutate_campaign_conversion_goals"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_criterion_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_criterion_service/__init__.py new file mode 100644 index 000000000..ae1beb5c7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_criterion_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignCriterionServiceClient + +__all__ = ("CampaignCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_criterion_service/client.py b/google/ads/googleads/v12/services/services/campaign_criterion_service/client.py new file mode 100644 index 000000000..d41a4b505 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_criterion_service/client.py @@ -0,0 +1,524 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignCriterionServiceGrpcTransport + + +class CampaignCriterionServiceClientMeta(type): + """Metaclass for the CampaignCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignCriterionServiceTransport]] + _transport_registry["grpc"] = CampaignCriterionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignCriterionServiceClient( + metaclass=CampaignCriterionServiceClientMeta +): + """Service to manage campaign criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignCriterionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignCriterionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignCriterionServiceTransport): + # transport is a CampaignCriterionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_criteria( + self, + request: Union[ + campaign_criterion_service.MutateCampaignCriteriaRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_criterion_service.CampaignCriterionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_criterion_service.MutateCampaignCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignCriteriaRequest, dict]): + The request object. Request message for + [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v12.services.CampaignCriterionService.MutateCampaignCriteria]. + customer_id (str): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignCriteriaResponse: + Response message for campaign + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_criterion_service.MutateCampaignCriteriaRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_criterion_service.MutateCampaignCriteriaRequest + ): + request = campaign_criterion_service.MutateCampaignCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/__init__.py new file mode 100644 index 000000000..9e5fcdee8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignCriterionServiceTransport +from .grpc import CampaignCriterionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignCriterionServiceTransport]] +_transport_registry["grpc"] = CampaignCriterionServiceGrpcTransport + +__all__ = ( + "CampaignCriterionServiceTransport", + "CampaignCriterionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/base.py new file mode 100644 index 000000000..ff283719c --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_criterion_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignCriterionServiceTransport(abc.ABC): + """Abstract transport class for CampaignCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_criteria: gapic_v1.method.wrap_method( + self.mutate_campaign_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_criteria( + self, + ) -> Callable[ + [campaign_criterion_service.MutateCampaignCriteriaRequest], + Union[ + campaign_criterion_service.MutateCampaignCriteriaResponse, + Awaitable[ + campaign_criterion_service.MutateCampaignCriteriaResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignCriterionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/grpc.py new file mode 100644 index 000000000..2363c59bc --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_criterion_service/transports/grpc.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_criterion_service +from .base import CampaignCriterionServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignCriterionServiceGrpcTransport(CampaignCriterionServiceTransport): + """gRPC backend transport for CampaignCriterionService. + + Service to manage campaign criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_criteria( + self, + ) -> Callable[ + [campaign_criterion_service.MutateCampaignCriteriaRequest], + campaign_criterion_service.MutateCampaignCriteriaResponse, + ]: + r"""Return a callable for the mutate campaign criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignCriteriaRequest], + ~.MutateCampaignCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_criteria" not in self._stubs: + self._stubs[ + "mutate_campaign_criteria" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignCriterionService/MutateCampaignCriteria", + request_serializer=campaign_criterion_service.MutateCampaignCriteriaRequest.serialize, + response_deserializer=campaign_criterion_service.MutateCampaignCriteriaResponse.deserialize, + ) + return self._stubs["mutate_campaign_criteria"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_customizer_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_customizer_service/__init__.py new file mode 100644 index 000000000..0417bca34 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_customizer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignCustomizerServiceClient + +__all__ = ("CampaignCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_customizer_service/client.py b/google/ads/googleads/v12/services/services/campaign_customizer_service/client.py new file mode 100644 index 000000000..aa04cbf93 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_customizer_service/client.py @@ -0,0 +1,532 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignCustomizerServiceGrpcTransport + + +class CampaignCustomizerServiceClientMeta(type): + """Metaclass for the CampaignCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignCustomizerServiceTransport]] + _transport_registry["grpc"] = CampaignCustomizerServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignCustomizerServiceClient( + metaclass=CampaignCustomizerServiceClientMeta +): + """Service to manage campaign customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, campaign_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignCustomizerServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignCustomizerServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignCustomizerServiceTransport): + # transport is a CampaignCustomizerServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_customizers( + self, + request: Union[ + campaign_customizer_service.MutateCampaignCustomizersRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_customizer_service.CampaignCustomizerOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_customizer_service.MutateCampaignCustomizersResponse: + r"""Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignCustomizersRequest, dict]): + The request object. Request message for + [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v12.services.CampaignCustomizerService.MutateCampaignCustomizers]. + customer_id (str): + Required. The ID of the customer + whose campaign customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignCustomizerOperation]): + Required. The list of operations to + perform on individual campaign + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignCustomizersResponse: + Response message for an campaign + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_customizer_service.MutateCampaignCustomizersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + campaign_customizer_service.MutateCampaignCustomizersRequest, + ): + request = campaign_customizer_service.MutateCampaignCustomizersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/__init__.py new file mode 100644 index 000000000..6da31d2b0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignCustomizerServiceTransport +from .grpc import CampaignCustomizerServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignCustomizerServiceTransport]] +_transport_registry["grpc"] = CampaignCustomizerServiceGrpcTransport + +__all__ = ( + "CampaignCustomizerServiceTransport", + "CampaignCustomizerServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/base.py new file mode 100644 index 000000000..cea0c2b9b --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_customizer_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignCustomizerServiceTransport(abc.ABC): + """Abstract transport class for CampaignCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_customizers: gapic_v1.method.wrap_method( + self.mutate_campaign_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_customizers( + self, + ) -> Callable[ + [campaign_customizer_service.MutateCampaignCustomizersRequest], + Union[ + campaign_customizer_service.MutateCampaignCustomizersResponse, + Awaitable[ + campaign_customizer_service.MutateCampaignCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignCustomizerServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/grpc.py new file mode 100644 index 000000000..16c61b500 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_customizer_service/transports/grpc.py @@ -0,0 +1,273 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_customizer_service +from .base import CampaignCustomizerServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignCustomizerServiceGrpcTransport( + CampaignCustomizerServiceTransport +): + """gRPC backend transport for CampaignCustomizerService. + + Service to manage campaign customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_customizers( + self, + ) -> Callable[ + [campaign_customizer_service.MutateCampaignCustomizersRequest], + campaign_customizer_service.MutateCampaignCustomizersResponse, + ]: + r"""Return a callable for the mutate campaign customizers method over gRPC. + + Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignCustomizersRequest], + ~.MutateCampaignCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_customizers" not in self._stubs: + self._stubs[ + "mutate_campaign_customizers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignCustomizerService/MutateCampaignCustomizers", + request_serializer=campaign_customizer_service.MutateCampaignCustomizersRequest.serialize, + response_deserializer=campaign_customizer_service.MutateCampaignCustomizersResponse.deserialize, + ) + return self._stubs["mutate_campaign_customizers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_draft_service/__init__.py new file mode 100644 index 000000000..4bd4221e9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignDraftServiceClient + +__all__ = ("CampaignDraftServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/client.py b/google/ads/googleads/v12/services/services/campaign_draft_service/client.py new file mode 100644 index 000000000..3647ab683 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/client.py @@ -0,0 +1,732 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.services.campaign_draft_service import ( + pagers, +) +from google.ads.googleads.v12.services.types import campaign_draft_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignDraftServiceGrpcTransport + + +class CampaignDraftServiceClientMeta(type): + """Metaclass for the CampaignDraftService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignDraftServiceTransport]] + _transport_registry["grpc"] = CampaignDraftServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignDraftServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignDraftServiceClient(metaclass=CampaignDraftServiceClientMeta): + """Service to manage campaign drafts.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignDraftServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignDraftServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, base_campaign_id: str, draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignDraftServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign draft service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignDraftServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignDraftServiceTransport): + # transport is a CampaignDraftServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_drafts( + self, + request: Union[ + campaign_draft_service.MutateCampaignDraftsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_draft_service.CampaignDraftOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_draft_service.MutateCampaignDraftsResponse: + r"""Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignDraftsRequest, dict]): + The request object. Request message for + [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v12.services.CampaignDraftService.MutateCampaignDrafts]. + customer_id (str): + Required. The ID of the customer + whose campaign drafts are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignDraftOperation]): + Required. The list of operations to + perform on individual campaign drafts. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignDraftsResponse: + Response message for campaign draft + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_draft_service.MutateCampaignDraftsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_draft_service.MutateCampaignDraftsRequest + ): + request = campaign_draft_service.MutateCampaignDraftsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_drafts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def promote_campaign_draft( + self, + request: Union[ + campaign_draft_service.PromoteCampaignDraftRequest, dict + ] = None, + *, + campaign_draft: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use [Operations.GetOperation] to poll the + LRO until it is done. Only a done status is returned in the + response. See the status in the Campaign Draft resource to + determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.PromoteCampaignDraftRequest, dict]): + The request object. Request message for + [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v12.services.CampaignDraftService.PromoteCampaignDraft]. + campaign_draft (str): + Required. The resource name of the + campaign draft to promote. + + This corresponds to the ``campaign_draft`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([campaign_draft]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_draft_service.PromoteCampaignDraftRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_draft_service.PromoteCampaignDraftRequest + ): + request = campaign_draft_service.PromoteCampaignDraftRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if campaign_draft is not None: + request.campaign_draft = campaign_draft + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.promote_campaign_draft + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("campaign_draft", request.campaign_draft),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=empty_pb2.Empty, + ) + + # Done; return the response. + return response + + def list_campaign_draft_async_errors( + self, + request: Union[ + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListCampaignDraftAsyncErrorsPager: + r"""Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListCampaignDraftAsyncErrorsRequest, dict]): + The request object. Request message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + resource_name (str): + Required. The name of the campaign + draft from which to retrieve the async + errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.campaign_draft_service.pagers.ListCampaignDraftAsyncErrorsPager: + Response message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_draft_service.ListCampaignDraftAsyncErrorsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_draft_service.ListCampaignDraftAsyncErrorsRequest + ): + request = campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_campaign_draft_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListCampaignDraftAsyncErrorsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignDraftServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/pagers.py b/google/ads/googleads/v12/services/services/campaign_draft_service/pagers.py new file mode 100644 index 000000000..d42a1a1c9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/pagers.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.services.types import campaign_draft_service +from google.rpc import status_pb2 # type: ignore + + +class ListCampaignDraftAsyncErrorsPager: + """A pager for iterating through ``list_campaign_draft_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.ListCampaignDraftAsyncErrorsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCampaignDraftAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.ListCampaignDraftAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ], + request: campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, + response: campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.ListCampaignDraftAsyncErrorsRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.ListCampaignDraftAsyncErrorsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterable[campaign_draft_service.ListCampaignDraftAsyncErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__(self) -> Iterator[status_pb2.Status]: + for page in self.pages: + yield from page.errors + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/__init__.py new file mode 100644 index 000000000..360bb0057 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignDraftServiceTransport +from .grpc import CampaignDraftServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignDraftServiceTransport]] +_transport_registry["grpc"] = CampaignDraftServiceGrpcTransport + +__all__ = ( + "CampaignDraftServiceTransport", + "CampaignDraftServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/base.py new file mode 100644 index 000000000..3e9dca089 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/base.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_draft_service +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignDraftServiceTransport(abc.ABC): + """Abstract transport class for CampaignDraftService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_drafts: gapic_v1.method.wrap_method( + self.mutate_campaign_drafts, + default_timeout=None, + client_info=client_info, + ), + self.promote_campaign_draft: gapic_v1.method.wrap_method( + self.promote_campaign_draft, + default_timeout=None, + client_info=client_info, + ), + self.list_campaign_draft_async_errors: gapic_v1.method.wrap_method( + self.list_campaign_draft_async_errors, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_campaign_drafts( + self, + ) -> Callable[ + [campaign_draft_service.MutateCampaignDraftsRequest], + Union[ + campaign_draft_service.MutateCampaignDraftsResponse, + Awaitable[campaign_draft_service.MutateCampaignDraftsResponse], + ], + ]: + raise NotImplementedError() + + @property + def promote_campaign_draft( + self, + ) -> Callable[ + [campaign_draft_service.PromoteCampaignDraftRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_campaign_draft_async_errors( + self, + ) -> Callable[ + [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], + Union[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + Awaitable[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignDraftServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_draft_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/grpc.py new file mode 100644 index 000000000..6902c0f94 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_draft_service/transports/grpc.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_draft_service +from google.longrunning import operations_pb2 # type: ignore +from .base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignDraftServiceGrpcTransport(CampaignDraftServiceTransport): + """gRPC backend transport for CampaignDraftService. + + Service to manage campaign drafts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: 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 channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_campaign_drafts( + self, + ) -> Callable[ + [campaign_draft_service.MutateCampaignDraftsRequest], + campaign_draft_service.MutateCampaignDraftsResponse, + ]: + r"""Return a callable for the mutate campaign drafts method over gRPC. + + Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignDraftsRequest], + ~.MutateCampaignDraftsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_drafts" not in self._stubs: + self._stubs[ + "mutate_campaign_drafts" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignDraftService/MutateCampaignDrafts", + request_serializer=campaign_draft_service.MutateCampaignDraftsRequest.serialize, + response_deserializer=campaign_draft_service.MutateCampaignDraftsResponse.deserialize, + ) + return self._stubs["mutate_campaign_drafts"] + + @property + def promote_campaign_draft( + self, + ) -> Callable[ + [campaign_draft_service.PromoteCampaignDraftRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the promote campaign draft method over gRPC. + + Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use [Operations.GetOperation] to poll the + LRO until it is done. Only a done status is returned in the + response. See the status in the Campaign Draft resource to + determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteCampaignDraftRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_campaign_draft" not in self._stubs: + self._stubs[ + "promote_campaign_draft" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignDraftService/PromoteCampaignDraft", + request_serializer=campaign_draft_service.PromoteCampaignDraftRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["promote_campaign_draft"] + + @property + def list_campaign_draft_async_errors( + self, + ) -> Callable[ + [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + ]: + r"""Return a callable for the list campaign draft async + errors method over gRPC. + + Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListCampaignDraftAsyncErrorsRequest], + ~.ListCampaignDraftAsyncErrorsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_campaign_draft_async_errors" not in self._stubs: + self._stubs[ + "list_campaign_draft_async_errors" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignDraftService/ListCampaignDraftAsyncErrors", + request_serializer=campaign_draft_service.ListCampaignDraftAsyncErrorsRequest.serialize, + response_deserializer=campaign_draft_service.ListCampaignDraftAsyncErrorsResponse.deserialize, + ) + return self._stubs["list_campaign_draft_async_errors"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignDraftServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_extension_setting_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/__init__.py new file mode 100644 index 000000000..a0b7711d8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignExtensionSettingServiceClient + +__all__ = ("CampaignExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_extension_setting_service/client.py b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/client.py new file mode 100644 index 000000000..56bd92d42 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/client.py @@ -0,0 +1,547 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_extension_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignExtensionSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignExtensionSettingServiceGrpcTransport + + +class CampaignExtensionSettingServiceClientMeta(type): + """Metaclass for the CampaignExtensionSettingService 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[CampaignExtensionSettingServiceTransport]] + _transport_registry["grpc"] = CampaignExtensionSettingServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignExtensionSettingServiceTransport]: + """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 CampaignExtensionSettingServiceClient( + metaclass=CampaignExtensionSettingServiceClientMeta +): + """Service to manage campaign extension settings.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignExtensionSettingServiceClient: 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: + CampaignExtensionSettingServiceClient: 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) -> CampaignExtensionSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignExtensionSettingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_extension_setting_path( + customer_id: str, campaign_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified campaign_extension_setting string.""" + return "customers/{customer_id}/campaignExtensionSettings/{campaign_id}~{extension_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_campaign_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a campaign_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CampaignExtensionSettingServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign extension setting service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignExtensionSettingServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignExtensionSettingServiceTransport): + # transport is a CampaignExtensionSettingServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_extension_settings( + self, + request: Union[ + campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_extension_setting_service.CampaignExtensionSettingOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_extension_setting_service.MutateCampaignExtensionSettingsResponse: + r"""Creates, updates, or removes campaign extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignExtensionSettingsRequest, dict]): + The request object. Request message for + [CampaignExtensionSettingService.MutateCampaignExtensionSettings][google.ads.googleads.v12.services.CampaignExtensionSettingService.MutateCampaignExtensionSettings]. + customer_id (str): + Required. The ID of the customer + whose campaign extension settings are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignExtensionSettingOperation]): + Required. The list of operations to + perform on individual campaign extension + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignExtensionSettingsResponse: + Response message for a campaign + extension setting mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest, + ): + request = campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_extension_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/__init__.py new file mode 100644 index 000000000..c6e29fc3d --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignExtensionSettingServiceTransport +from .grpc import CampaignExtensionSettingServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignExtensionSettingServiceTransport]] +_transport_registry["grpc"] = CampaignExtensionSettingServiceGrpcTransport + +__all__ = ( + "CampaignExtensionSettingServiceTransport", + "CampaignExtensionSettingServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/base.py new file mode 100644 index 000000000..2955a449a --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_extension_setting_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignExtensionSettingServiceTransport(abc.ABC): + """Abstract transport class for CampaignExtensionSettingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_extension_settings: gapic_v1.method.wrap_method( + self.mutate_campaign_extension_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_extension_settings( + self, + ) -> Callable[ + [ + campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest + ], + Union[ + campaign_extension_setting_service.MutateCampaignExtensionSettingsResponse, + Awaitable[ + campaign_extension_setting_service.MutateCampaignExtensionSettingsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignExtensionSettingServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/grpc.py new file mode 100644 index 000000000..232479eec --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_extension_setting_service/transports/grpc.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + campaign_extension_setting_service, +) +from .base import CampaignExtensionSettingServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignExtensionSettingServiceGrpcTransport( + CampaignExtensionSettingServiceTransport +): + """gRPC backend transport for CampaignExtensionSettingService. + + Service to manage campaign extension settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_extension_settings( + self, + ) -> Callable[ + [ + campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest + ], + campaign_extension_setting_service.MutateCampaignExtensionSettingsResponse, + ]: + r"""Return a callable for the mutate campaign extension + settings method over gRPC. + + Creates, updates, or removes campaign extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCampaignExtensionSettingsRequest], + ~.MutateCampaignExtensionSettingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_extension_settings" not in self._stubs: + self._stubs[ + "mutate_campaign_extension_settings" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignExtensionSettingService/MutateCampaignExtensionSettings", + request_serializer=campaign_extension_setting_service.MutateCampaignExtensionSettingsRequest.serialize, + response_deserializer=campaign_extension_setting_service.MutateCampaignExtensionSettingsResponse.deserialize, + ) + return self._stubs["mutate_campaign_extension_settings"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignExtensionSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_feed_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_feed_service/__init__.py new file mode 100644 index 000000000..128850746 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_feed_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignFeedServiceClient + +__all__ = ("CampaignFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_feed_service/client.py b/google/ads/googleads/v12/services/services/campaign_feed_service/client.py new file mode 100644 index 000000000..e9937d60f --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_feed_service/client.py @@ -0,0 +1,527 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_feed_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignFeedServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignFeedServiceGrpcTransport + + +class CampaignFeedServiceClientMeta(type): + """Metaclass for the CampaignFeedService 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[CampaignFeedServiceTransport]] + _transport_registry["grpc"] = CampaignFeedServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignFeedServiceTransport]: + """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 CampaignFeedServiceClient(metaclass=CampaignFeedServiceClientMeta): + """Service to manage campaign feeds.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignFeedServiceClient: 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: + CampaignFeedServiceClient: 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) -> CampaignFeedServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignFeedServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_feed_path( + customer_id: str, campaign_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified campaign_feed string.""" + return "customers/{customer_id}/campaignFeeds/{campaign_id}~{feed_id}".format( + customer_id=customer_id, campaign_id=campaign_id, feed_id=feed_id, + ) + + @staticmethod + def parse_campaign_feed_path(path: str) -> Dict[str, str]: + """Parses a campaign_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignFeedServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign feed 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 (Union[str, CampaignFeedServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignFeedServiceTransport): + # transport is a CampaignFeedServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_feeds( + self, + request: Union[ + campaign_feed_service.MutateCampaignFeedsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_feed_service.CampaignFeedOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_feed_service.MutateCampaignFeedsResponse: + r"""Creates, updates, or removes campaign feeds. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignFeedError <>`__ + `CollectionSizeError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignFeedsRequest, dict]): + The request object. Request message for + [CampaignFeedService.MutateCampaignFeeds][google.ads.googleads.v12.services.CampaignFeedService.MutateCampaignFeeds]. + customer_id (str): + Required. The ID of the customer + whose campaign feeds are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignFeedOperation]): + Required. The list of operations to + perform on individual campaign feeds. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignFeedsResponse: + Response message for a campaign feed + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_feed_service.MutateCampaignFeedsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_feed_service.MutateCampaignFeedsRequest + ): + request = campaign_feed_service.MutateCampaignFeedsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_feeds + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_feed_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/__init__.py new file mode 100644 index 000000000..d9eda8a97 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignFeedServiceTransport +from .grpc import CampaignFeedServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignFeedServiceTransport]] +_transport_registry["grpc"] = CampaignFeedServiceGrpcTransport + +__all__ = ( + "CampaignFeedServiceTransport", + "CampaignFeedServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_feed_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/base.py new file mode 100644 index 000000000..c6656fd69 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_feed_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignFeedServiceTransport(abc.ABC): + """Abstract transport class for CampaignFeedService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_feeds: gapic_v1.method.wrap_method( + self.mutate_campaign_feeds, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_feeds( + self, + ) -> Callable[ + [campaign_feed_service.MutateCampaignFeedsRequest], + Union[ + campaign_feed_service.MutateCampaignFeedsResponse, + Awaitable[campaign_feed_service.MutateCampaignFeedsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignFeedServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_feed_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/grpc.py new file mode 100644 index 000000000..9988a16f9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_feed_service/transports/grpc.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_feed_service +from .base import CampaignFeedServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignFeedServiceGrpcTransport(CampaignFeedServiceTransport): + """gRPC backend transport for CampaignFeedService. + + Service to manage campaign feeds. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_feeds( + self, + ) -> Callable[ + [campaign_feed_service.MutateCampaignFeedsRequest], + campaign_feed_service.MutateCampaignFeedsResponse, + ]: + r"""Return a callable for the mutate campaign feeds method over gRPC. + + Creates, updates, or removes campaign feeds. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignFeedError <>`__ + `CollectionSizeError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignFeedsRequest], + ~.MutateCampaignFeedsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_feeds" not in self._stubs: + self._stubs[ + "mutate_campaign_feeds" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignFeedService/MutateCampaignFeeds", + request_serializer=campaign_feed_service.MutateCampaignFeedsRequest.serialize, + response_deserializer=campaign_feed_service.MutateCampaignFeedsResponse.deserialize, + ) + return self._stubs["mutate_campaign_feeds"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignFeedServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_group_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_group_service/__init__.py new file mode 100644 index 000000000..7b821d363 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_group_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignGroupServiceClient + +__all__ = ("CampaignGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_group_service/client.py b/google/ads/googleads/v12/services/services/campaign_group_service/client.py new file mode 100644 index 000000000..e5b096a0f --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_group_service/client.py @@ -0,0 +1,486 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignGroupServiceGrpcTransport + + +class CampaignGroupServiceClientMeta(type): + """Metaclass for the CampaignGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignGroupServiceTransport]] + _transport_registry["grpc"] = CampaignGroupServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignGroupServiceClient(metaclass=CampaignGroupServiceClientMeta): + """Service to manage campaign groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_group_path(customer_id: str, campaign_group_id: str,) -> str: + """Returns a fully-qualified campaign_group string.""" + return "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, campaign_group_id=campaign_group_id, + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignGroupServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignGroupServiceTransport): + # transport is a CampaignGroupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_groups( + self, + request: Union[ + campaign_group_service.MutateCampaignGroupsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_group_service.CampaignGroupOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_group_service.MutateCampaignGroupsResponse: + r"""Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignGroupsRequest, dict]): + The request object. Request message for + [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v12.services.CampaignGroupService.MutateCampaignGroups]. + customer_id (str): + Required. The ID of the customer + whose campaign groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignGroupOperation]): + Required. The list of operations to + perform on individual campaign groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignGroupsResponse: + Response message for campaign group + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_group_service.MutateCampaignGroupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_group_service.MutateCampaignGroupsRequest + ): + request = campaign_group_service.MutateCampaignGroupsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_group_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_group_service/transports/__init__.py new file mode 100644 index 000000000..807e02b53 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_group_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignGroupServiceTransport +from .grpc import CampaignGroupServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignGroupServiceTransport]] +_transport_registry["grpc"] = CampaignGroupServiceGrpcTransport + +__all__ = ( + "CampaignGroupServiceTransport", + "CampaignGroupServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_group_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_group_service/transports/base.py new file mode 100644 index 000000000..65bbc9e48 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_group_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_group_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignGroupServiceTransport(abc.ABC): + """Abstract transport class for CampaignGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_groups: gapic_v1.method.wrap_method( + self.mutate_campaign_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_groups( + self, + ) -> Callable[ + [campaign_group_service.MutateCampaignGroupsRequest], + Union[ + campaign_group_service.MutateCampaignGroupsResponse, + Awaitable[campaign_group_service.MutateCampaignGroupsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignGroupServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_group_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_group_service/transports/grpc.py new file mode 100644 index 000000000..d5cb4f8f6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_group_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_group_service +from .base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignGroupServiceGrpcTransport(CampaignGroupServiceTransport): + """gRPC backend transport for CampaignGroupService. + + Service to manage campaign groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_groups( + self, + ) -> Callable[ + [campaign_group_service.MutateCampaignGroupsRequest], + campaign_group_service.MutateCampaignGroupsResponse, + ]: + r"""Return a callable for the mutate campaign groups method over gRPC. + + Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignGroupsRequest], + ~.MutateCampaignGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_groups" not in self._stubs: + self._stubs[ + "mutate_campaign_groups" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignGroupService/MutateCampaignGroups", + request_serializer=campaign_group_service.MutateCampaignGroupsRequest.serialize, + response_deserializer=campaign_group_service.MutateCampaignGroupsResponse.deserialize, + ) + return self._stubs["mutate_campaign_groups"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_label_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_label_service/__init__.py new file mode 100644 index 000000000..d2465e9d8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignLabelServiceClient + +__all__ = ("CampaignLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_label_service/client.py b/google/ads/googleads/v12/services/services/campaign_label_service/client.py new file mode 100644 index 000000000..d8b364c9d --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_label_service/client.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignLabelServiceGrpcTransport + + +class CampaignLabelServiceClientMeta(type): + """Metaclass for the CampaignLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignLabelServiceTransport]] + _transport_registry["grpc"] = CampaignLabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignLabelServiceClient(metaclass=CampaignLabelServiceClientMeta): + """Service to manage labels on campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, campaign_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, campaign_id=campaign_id, label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignLabelServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignLabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignLabelServiceTransport): + # transport is a CampaignLabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_labels( + self, + request: Union[ + campaign_label_service.MutateCampaignLabelsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_label_service.CampaignLabelOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_label_service.MutateCampaignLabelsResponse: + r"""Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignLabelsRequest, dict]): + The request object. Request message for + [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v12.services.CampaignLabelService.MutateCampaignLabels]. + customer_id (str): + Required. ID of the customer whose + campaign-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignLabelOperation]): + Required. The list of operations to + perform on campaign-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignLabelsResponse: + Response message for a campaign + labels mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_label_service.MutateCampaignLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_label_service.MutateCampaignLabelsRequest + ): + request = campaign_label_service.MutateCampaignLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_label_service/transports/__init__.py new file mode 100644 index 000000000..307ce77af --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignLabelServiceTransport +from .grpc import CampaignLabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignLabelServiceTransport]] +_transport_registry["grpc"] = CampaignLabelServiceGrpcTransport + +__all__ = ( + "CampaignLabelServiceTransport", + "CampaignLabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_label_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_label_service/transports/base.py new file mode 100644 index 000000000..a3518156b --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_label_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_label_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignLabelServiceTransport(abc.ABC): + """Abstract transport class for CampaignLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_labels: gapic_v1.method.wrap_method( + self.mutate_campaign_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_labels( + self, + ) -> Callable[ + [campaign_label_service.MutateCampaignLabelsRequest], + Union[ + campaign_label_service.MutateCampaignLabelsResponse, + Awaitable[campaign_label_service.MutateCampaignLabelsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignLabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_label_service/transports/grpc.py new file mode 100644 index 000000000..d54a9b73f --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_label_service/transports/grpc.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_label_service +from .base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignLabelServiceGrpcTransport(CampaignLabelServiceTransport): + """gRPC backend transport for CampaignLabelService. + + Service to manage labels on campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_labels( + self, + ) -> Callable[ + [campaign_label_service.MutateCampaignLabelsRequest], + campaign_label_service.MutateCampaignLabelsResponse, + ]: + r"""Return a callable for the mutate campaign labels method over gRPC. + + Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignLabelsRequest], + ~.MutateCampaignLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_labels" not in self._stubs: + self._stubs[ + "mutate_campaign_labels" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignLabelService/MutateCampaignLabels", + request_serializer=campaign_label_service.MutateCampaignLabelsRequest.serialize, + response_deserializer=campaign_label_service.MutateCampaignLabelsResponse.deserialize, + ) + return self._stubs["mutate_campaign_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_service/__init__.py new file mode 100644 index 000000000..fc70ff486 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignServiceClient + +__all__ = ("CampaignServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_service/client.py b/google/ads/googleads/v12/services/services/campaign_service/client.py new file mode 100644 index 000000000..970d6ed63 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_service/client.py @@ -0,0 +1,609 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignServiceGrpcTransport + + +class CampaignServiceClientMeta(type): + """Metaclass for the CampaignService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignServiceTransport]] + _transport_registry["grpc"] = CampaignServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignServiceClient(metaclass=CampaignServiceClientMeta): + """Service to manage campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path(customer_id: str, campaign_budget_id: str,) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path(customer_id: str, campaign_group_id: str,) -> str: + """Returns a fully-qualified campaign_group string.""" + return "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, campaign_group_id=campaign_group_id, + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, campaign_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, campaign_id=campaign_id, label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignServiceTransport): + # transport is a CampaignServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaigns( + self, + request: Union[campaign_service.MutateCampaignsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[campaign_service.CampaignOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_service.MutateCampaignsResponse: + r"""Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignsRequest, dict]): + The request object. Request message for + [CampaignService.MutateCampaigns][google.ads.googleads.v12.services.CampaignService.MutateCampaigns]. + customer_id (str): + Required. The ID of the customer + whose campaigns are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignOperation]): + Required. The list of operations to + perform on individual campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_service.MutateCampaignsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, campaign_service.MutateCampaignsRequest): + request = campaign_service.MutateCampaignsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_campaigns] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_service/transports/__init__.py new file mode 100644 index 000000000..d4135b6e6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignServiceTransport +from .grpc import CampaignServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignServiceTransport]] +_transport_registry["grpc"] = CampaignServiceGrpcTransport + +__all__ = ( + "CampaignServiceTransport", + "CampaignServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_service/transports/base.py new file mode 100644 index 000000000..7464d0c59 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignServiceTransport(abc.ABC): + """Abstract transport class for CampaignService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaigns: gapic_v1.method.wrap_method( + self.mutate_campaigns, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaigns( + self, + ) -> Callable[ + [campaign_service.MutateCampaignsRequest], + Union[ + campaign_service.MutateCampaignsResponse, + Awaitable[campaign_service.MutateCampaignsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_service/transports/grpc.py new file mode 100644 index 000000000..d8e8163e8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_service/transports/grpc.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_service +from .base import CampaignServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignServiceGrpcTransport(CampaignServiceTransport): + """gRPC backend transport for CampaignService. + + Service to manage campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaigns( + self, + ) -> Callable[ + [campaign_service.MutateCampaignsRequest], + campaign_service.MutateCampaignsResponse, + ]: + r"""Return a callable for the mutate campaigns method over gRPC. + + Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCampaignsRequest], + ~.MutateCampaignsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaigns" not in self._stubs: + self._stubs["mutate_campaigns"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignService/MutateCampaigns", + request_serializer=campaign_service.MutateCampaignsRequest.serialize, + response_deserializer=campaign_service.MutateCampaignsResponse.deserialize, + ) + return self._stubs["mutate_campaigns"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_shared_set_service/__init__.py b/google/ads/googleads/v12/services/services/campaign_shared_set_service/__init__.py new file mode 100644 index 000000000..1a5b7996c --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_shared_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CampaignSharedSetServiceClient + +__all__ = ("CampaignSharedSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_shared_set_service/client.py b/google/ads/googleads/v12/services/services/campaign_shared_set_service/client.py new file mode 100644 index 000000000..13b191b3c --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_shared_set_service/client.py @@ -0,0 +1,538 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import campaign_shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignSharedSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignSharedSetServiceGrpcTransport + + +class CampaignSharedSetServiceClientMeta(type): + """Metaclass for the CampaignSharedSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignSharedSetServiceTransport]] + _transport_registry["grpc"] = CampaignSharedSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CampaignSharedSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignSharedSetServiceClient( + metaclass=CampaignSharedSetServiceClientMeta +): + """Service to manage campaign shared sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignSharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignSharedSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, campaign_id: str, shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path(customer_id: str, shared_set_id: str,) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CampaignSharedSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign shared set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CampaignSharedSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CampaignSharedSetServiceTransport): + # transport is a CampaignSharedSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_campaign_shared_sets( + self, + request: Union[ + campaign_shared_set_service.MutateCampaignSharedSetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + campaign_shared_set_service.CampaignSharedSetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> campaign_shared_set_service.MutateCampaignSharedSetsResponse: + r"""Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCampaignSharedSetsRequest, dict]): + The request object. Request message for + [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v12.services.CampaignSharedSetService.MutateCampaignSharedSets]. + customer_id (str): + Required. The ID of the customer + whose campaign shared sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignSharedSetOperation]): + Required. The list of operations to + perform on individual campaign shared + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCampaignSharedSetsResponse: + Response message for a campaign + shared set mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a campaign_shared_set_service.MutateCampaignSharedSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, campaign_shared_set_service.MutateCampaignSharedSetsRequest + ): + request = campaign_shared_set_service.MutateCampaignSharedSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CampaignSharedSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/__init__.py new file mode 100644 index 000000000..4915ee02c --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CampaignSharedSetServiceTransport +from .grpc import CampaignSharedSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignSharedSetServiceTransport]] +_transport_registry["grpc"] = CampaignSharedSetServiceGrpcTransport + +__all__ = ( + "CampaignSharedSetServiceTransport", + "CampaignSharedSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/base.py b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/base.py new file mode 100644 index 000000000..801699116 --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import campaign_shared_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CampaignSharedSetServiceTransport(abc.ABC): + """Abstract transport class for CampaignSharedSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_shared_sets: gapic_v1.method.wrap_method( + self.mutate_campaign_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_shared_sets( + self, + ) -> Callable[ + [campaign_shared_set_service.MutateCampaignSharedSetsRequest], + Union[ + campaign_shared_set_service.MutateCampaignSharedSetsResponse, + Awaitable[ + campaign_shared_set_service.MutateCampaignSharedSetsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CampaignSharedSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/grpc.py new file mode 100644 index 000000000..0c0a9d79e --- /dev/null +++ b/google/ads/googleads/v12/services/services/campaign_shared_set_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import campaign_shared_set_service +from .base import CampaignSharedSetServiceTransport, DEFAULT_CLIENT_INFO + + +class CampaignSharedSetServiceGrpcTransport(CampaignSharedSetServiceTransport): + """gRPC backend transport for CampaignSharedSetService. + + Service to manage campaign shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_campaign_shared_sets( + self, + ) -> Callable[ + [campaign_shared_set_service.MutateCampaignSharedSetsRequest], + campaign_shared_set_service.MutateCampaignSharedSetsResponse, + ]: + r"""Return a callable for the mutate campaign shared sets method over gRPC. + + Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignSharedSetsRequest], + ~.MutateCampaignSharedSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_shared_sets" not in self._stubs: + self._stubs[ + "mutate_campaign_shared_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CampaignSharedSetService/MutateCampaignSharedSets", + request_serializer=campaign_shared_set_service.MutateCampaignSharedSetsRequest.serialize, + response_deserializer=campaign_shared_set_service.MutateCampaignSharedSetsResponse.deserialize, + ) + return self._stubs["mutate_campaign_shared_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CampaignSharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_action_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_action_service/__init__.py new file mode 100644 index 000000000..ac86a27da --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_action_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionActionServiceClient + +__all__ = ("ConversionActionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_action_service/client.py b/google/ads/googleads/v12/services/services/conversion_action_service/client.py new file mode 100644 index 000000000..7f4603739 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_action_service/client.py @@ -0,0 +1,513 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import conversion_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionActionServiceGrpcTransport + + +class ConversionActionServiceClientMeta(type): + """Metaclass for the ConversionActionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionActionServiceTransport]] + _transport_registry["grpc"] = ConversionActionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionActionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionActionServiceClient( + metaclass=ConversionActionServiceClientMeta +): + """Service to manage conversion actions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionActionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ConversionActionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion action service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionActionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionActionServiceTransport): + # transport is a ConversionActionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_conversion_actions( + self, + request: Union[ + conversion_action_service.MutateConversionActionsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + conversion_action_service.ConversionActionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_action_service.MutateConversionActionsResponse: + r"""Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateConversionActionsRequest, dict]): + The request object. Request message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v12.services.ConversionActionService.MutateConversionActions]. + customer_id (str): + Required. The ID of the customer + whose conversion actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionActionOperation]): + Required. The list of operations to + perform on individual conversion + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateConversionActionsResponse: + Response message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v12.services.ConversionActionService.MutateConversionActions]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_action_service.MutateConversionActionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, conversion_action_service.MutateConversionActionsRequest + ): + request = conversion_action_service.MutateConversionActionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionActionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_action_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_action_service/transports/__init__.py new file mode 100644 index 000000000..491db4a6b --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_action_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionActionServiceTransport +from .grpc import ConversionActionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionActionServiceTransport]] +_transport_registry["grpc"] = ConversionActionServiceGrpcTransport + +__all__ = ( + "ConversionActionServiceTransport", + "ConversionActionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_action_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_action_service/transports/base.py new file mode 100644 index 000000000..8674c4a73 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_action_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import conversion_action_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionActionServiceTransport(abc.ABC): + """Abstract transport class for ConversionActionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_actions: gapic_v1.method.wrap_method( + self.mutate_conversion_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_actions( + self, + ) -> Callable[ + [conversion_action_service.MutateConversionActionsRequest], + Union[ + conversion_action_service.MutateConversionActionsResponse, + Awaitable[ + conversion_action_service.MutateConversionActionsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionActionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_action_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_action_service/transports/grpc.py new file mode 100644 index 000000000..a8a564226 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_action_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import conversion_action_service +from .base import ConversionActionServiceTransport, DEFAULT_CLIENT_INFO + + +class ConversionActionServiceGrpcTransport(ConversionActionServiceTransport): + """gRPC backend transport for ConversionActionService. + + Service to manage conversion actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_conversion_actions( + self, + ) -> Callable[ + [conversion_action_service.MutateConversionActionsRequest], + conversion_action_service.MutateConversionActionsResponse, + ]: + r"""Return a callable for the mutate conversion actions method over gRPC. + + Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateConversionActionsRequest], + ~.MutateConversionActionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_actions" not in self._stubs: + self._stubs[ + "mutate_conversion_actions" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionActionService/MutateConversionActions", + request_serializer=conversion_action_service.MutateConversionActionsRequest.serialize, + response_deserializer=conversion_action_service.MutateConversionActionsResponse.deserialize, + ) + return self._stubs["mutate_conversion_actions"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/__init__.py new file mode 100644 index 000000000..f204c61b3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionAdjustmentUploadServiceClient + +__all__ = ("ConversionAdjustmentUploadServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/client.py b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/client.py new file mode 100644 index 000000000..773d0d43c --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/client.py @@ -0,0 +1,505 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_adjustment_upload_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionAdjustmentUploadServiceGrpcTransport + + +class ConversionAdjustmentUploadServiceClientMeta(type): + """Metaclass for the ConversionAdjustmentUploadService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionAdjustmentUploadServiceTransport]] + _transport_registry["grpc"] = ConversionAdjustmentUploadServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionAdjustmentUploadServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionAdjustmentUploadServiceClient( + metaclass=ConversionAdjustmentUploadServiceClientMeta +): + """Service to upload conversion adjustments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionAdjustmentUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionAdjustmentUploadServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, ConversionAdjustmentUploadServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion adjustment upload service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionAdjustmentUploadServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionAdjustmentUploadServiceTransport): + # transport is a ConversionAdjustmentUploadServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def upload_conversion_adjustments( + self, + request: Union[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + dict, + ] = None, + *, + customer_id: str = None, + conversion_adjustments: Sequence[ + conversion_adjustment_upload_service.ConversionAdjustment + ] = None, + partial_failure: bool = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse: + r"""Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.UploadConversionAdjustmentsRequest, dict]): + The request object. Request message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v12.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversion_adjustments (Sequence[google.ads.googleads.v12.services.types.ConversionAdjustment]): + Required. The conversion adjustments + that are being uploaded. + + This corresponds to the ``conversion_adjustments`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.UploadConversionAdjustmentsResponse: + Response message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v12.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [customer_id, conversion_adjustments, partial_failure] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + ): + request = conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversion_adjustments is not None: + request.conversion_adjustments = conversion_adjustments + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_conversion_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionAdjustmentUploadServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/__init__.py new file mode 100644 index 000000000..d33d0e3aa --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionAdjustmentUploadServiceTransport +from .grpc import ConversionAdjustmentUploadServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionAdjustmentUploadServiceTransport]] +_transport_registry["grpc"] = ConversionAdjustmentUploadServiceGrpcTransport + +__all__ = ( + "ConversionAdjustmentUploadServiceTransport", + "ConversionAdjustmentUploadServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/base.py new file mode 100644 index 000000000..a8ddbd90a --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_adjustment_upload_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionAdjustmentUploadServiceTransport(abc.ABC): + """Abstract transport class for ConversionAdjustmentUploadService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_conversion_adjustments: gapic_v1.method.wrap_method( + self.upload_conversion_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_conversion_adjustments( + self, + ) -> Callable[ + [ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest + ], + Union[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, + Awaitable[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionAdjustmentUploadServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/grpc.py new file mode 100644 index 000000000..2b44265b6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_adjustment_upload_service/transports/grpc.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_adjustment_upload_service, +) +from .base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class ConversionAdjustmentUploadServiceGrpcTransport( + ConversionAdjustmentUploadServiceTransport +): + """gRPC backend transport for ConversionAdjustmentUploadService. + + Service to upload conversion adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def upload_conversion_adjustments( + self, + ) -> Callable[ + [ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest + ], + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, + ]: + r"""Return a callable for the upload conversion adjustments method over gRPC. + + Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadConversionAdjustmentsRequest], + ~.UploadConversionAdjustmentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_conversion_adjustments" not in self._stubs: + self._stubs[ + "upload_conversion_adjustments" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionAdjustmentUploadService/UploadConversionAdjustments", + request_serializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest.serialize, + response_deserializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse.deserialize, + ) + return self._stubs["upload_conversion_adjustments"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionAdjustmentUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_custom_variable_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/__init__.py new file mode 100644 index 000000000..399bfed68 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionCustomVariableServiceClient + +__all__ = ("ConversionCustomVariableServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_custom_variable_service/client.py b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/client.py new file mode 100644 index 000000000..e46f97165 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/client.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_custom_variable_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionCustomVariableServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionCustomVariableServiceGrpcTransport + + +class ConversionCustomVariableServiceClientMeta(type): + """Metaclass for the ConversionCustomVariableService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionCustomVariableServiceTransport]] + _transport_registry["grpc"] = ConversionCustomVariableServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionCustomVariableServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionCustomVariableServiceClient( + metaclass=ConversionCustomVariableServiceClientMeta +): + """Service to manage conversion custom variables.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionCustomVariableServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionCustomVariableServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, ConversionCustomVariableServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion custom variable service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionCustomVariableServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionCustomVariableServiceTransport): + # transport is a ConversionCustomVariableServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_conversion_custom_variables( + self, + request: Union[ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + conversion_custom_variable_service.ConversionCustomVariableOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_custom_variable_service.MutateConversionCustomVariablesResponse: + r"""Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateConversionCustomVariablesRequest, dict]): + The request object. Request message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v12.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + customer_id (str): + Required. The ID of the customer + whose conversion custom variables are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionCustomVariableOperation]): + Required. The list of operations to + perform on individual conversion custom + variables. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateConversionCustomVariablesResponse: + Response message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v12.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_custom_variable_service.MutateConversionCustomVariablesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + ): + request = conversion_custom_variable_service.MutateConversionCustomVariablesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_custom_variables + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionCustomVariableServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/__init__.py new file mode 100644 index 000000000..ec008d6c5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionCustomVariableServiceTransport +from .grpc import ConversionCustomVariableServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionCustomVariableServiceTransport]] +_transport_registry["grpc"] = ConversionCustomVariableServiceGrpcTransport + +__all__ = ( + "ConversionCustomVariableServiceTransport", + "ConversionCustomVariableServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/base.py new file mode 100644 index 000000000..a4756c788 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_custom_variable_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionCustomVariableServiceTransport(abc.ABC): + """Abstract transport class for ConversionCustomVariableService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_custom_variables: gapic_v1.method.wrap_method( + self.mutate_conversion_custom_variables, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_custom_variables( + self, + ) -> Callable[ + [ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest + ], + Union[ + conversion_custom_variable_service.MutateConversionCustomVariablesResponse, + Awaitable[ + conversion_custom_variable_service.MutateConversionCustomVariablesResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionCustomVariableServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/grpc.py new file mode 100644 index 000000000..767320bb7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_custom_variable_service/transports/grpc.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_custom_variable_service, +) +from .base import ConversionCustomVariableServiceTransport, DEFAULT_CLIENT_INFO + + +class ConversionCustomVariableServiceGrpcTransport( + ConversionCustomVariableServiceTransport +): + """gRPC backend transport for ConversionCustomVariableService. + + Service to manage conversion custom variables. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_conversion_custom_variables( + self, + ) -> Callable[ + [ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest + ], + conversion_custom_variable_service.MutateConversionCustomVariablesResponse, + ]: + r"""Return a callable for the mutate conversion custom + variables method over gRPC. + + Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateConversionCustomVariablesRequest], + ~.MutateConversionCustomVariablesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_custom_variables" not in self._stubs: + self._stubs[ + "mutate_conversion_custom_variables" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionCustomVariableService/MutateConversionCustomVariables", + request_serializer=conversion_custom_variable_service.MutateConversionCustomVariablesRequest.serialize, + response_deserializer=conversion_custom_variable_service.MutateConversionCustomVariablesResponse.deserialize, + ) + return self._stubs["mutate_conversion_custom_variables"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionCustomVariableServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/__init__.py new file mode 100644 index 000000000..39608668b --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionGoalCampaignConfigServiceClient + +__all__ = ("ConversionGoalCampaignConfigServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/client.py b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/client.py new file mode 100644 index 000000000..470c8e84e --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/client.py @@ -0,0 +1,533 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_goal_campaign_config_service, +) +from .transports.base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionGoalCampaignConfigServiceGrpcTransport + + +class ConversionGoalCampaignConfigServiceClientMeta(type): + """Metaclass for the ConversionGoalCampaignConfigService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionGoalCampaignConfigServiceTransport]] + _transport_registry[ + "grpc" + ] = ConversionGoalCampaignConfigServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionGoalCampaignConfigServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionGoalCampaignConfigServiceClient( + metaclass=ConversionGoalCampaignConfigServiceClientMeta +): + """Service to manage conversion goal campaign config.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionGoalCampaignConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionGoalCampaignConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path(customer_id: str, goal_id: str,) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, ConversionGoalCampaignConfigServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion goal campaign config service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionGoalCampaignConfigServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionGoalCampaignConfigServiceTransport): + # transport is a ConversionGoalCampaignConfigServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_conversion_goal_campaign_configs( + self, + request: Union[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse: + r"""Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateConversionGoalCampaignConfigsRequest, dict]): + The request object. Request message for + [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfig][]. + customer_id (str): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionGoalCampaignConfigOperation]): + Required. The list of operations to + perform on individual conversion goal + campaign config. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateConversionGoalCampaignConfigsResponse: + Response message for a conversion + goal campaign config mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + ): + request = conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_goal_campaign_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionGoalCampaignConfigServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/__init__.py new file mode 100644 index 000000000..4b161d57a --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionGoalCampaignConfigServiceTransport +from .grpc import ConversionGoalCampaignConfigServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionGoalCampaignConfigServiceTransport]] +_transport_registry["grpc"] = ConversionGoalCampaignConfigServiceGrpcTransport + +__all__ = ( + "ConversionGoalCampaignConfigServiceTransport", + "ConversionGoalCampaignConfigServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/base.py new file mode 100644 index 000000000..89140242b --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_goal_campaign_config_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionGoalCampaignConfigServiceTransport(abc.ABC): + """Abstract transport class for ConversionGoalCampaignConfigService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_goal_campaign_configs: gapic_v1.method.wrap_method( + self.mutate_conversion_goal_campaign_configs, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_goal_campaign_configs( + self, + ) -> Callable[ + [ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest + ], + Union[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, + Awaitable[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionGoalCampaignConfigServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/grpc.py new file mode 100644 index 000000000..b6861b21a --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_goal_campaign_config_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_goal_campaign_config_service, +) +from .base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class ConversionGoalCampaignConfigServiceGrpcTransport( + ConversionGoalCampaignConfigServiceTransport +): + """gRPC backend transport for ConversionGoalCampaignConfigService. + + Service to manage conversion goal campaign config. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_conversion_goal_campaign_configs( + self, + ) -> Callable[ + [ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest + ], + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, + ]: + r"""Return a callable for the mutate conversion goal + campaign configs method over gRPC. + + Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionGoalCampaignConfigsRequest], + ~.MutateConversionGoalCampaignConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_goal_campaign_configs" not in self._stubs: + self._stubs[ + "mutate_conversion_goal_campaign_configs" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionGoalCampaignConfigService/MutateConversionGoalCampaignConfigs", + request_serializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest.serialize, + response_deserializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse.deserialize, + ) + return self._stubs["mutate_conversion_goal_campaign_configs"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionGoalCampaignConfigServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_upload_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_upload_service/__init__.py new file mode 100644 index 000000000..be2a8432b --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_upload_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionUploadServiceClient + +__all__ = ("ConversionUploadServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_upload_service/client.py b/google/ads/googleads/v12/services/services/conversion_upload_service/client.py new file mode 100644 index 000000000..098a8f669 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_upload_service/client.py @@ -0,0 +1,631 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import conversion_upload_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionUploadServiceGrpcTransport + + +class ConversionUploadServiceClientMeta(type): + """Metaclass for the ConversionUploadService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionUploadServiceTransport]] + _transport_registry["grpc"] = ConversionUploadServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionUploadServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionUploadServiceClient( + metaclass=ConversionUploadServiceClientMeta +): + """Service to upload conversions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionUploadServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ConversionUploadServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion upload service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionUploadServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionUploadServiceTransport): + # transport is a ConversionUploadServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def upload_click_conversions( + self, + request: Union[ + conversion_upload_service.UploadClickConversionsRequest, dict + ] = None, + *, + customer_id: str = None, + conversions: Sequence[conversion_upload_service.ClickConversion] = None, + partial_failure: bool = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_upload_service.UploadClickConversionsResponse: + r"""Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.UploadClickConversionsRequest, dict]): + The request object. Request message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadClickConversions]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (Sequence[google.ads.googleads.v12.services.types.ClickConversion]): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.UploadClickConversionsResponse: + Response message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadClickConversions]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, conversions, partial_failure]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_upload_service.UploadClickConversionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, conversion_upload_service.UploadClickConversionsRequest + ): + request = conversion_upload_service.UploadClickConversionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversions is not None: + request.conversions = conversions + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_click_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def upload_call_conversions( + self, + request: Union[ + conversion_upload_service.UploadCallConversionsRequest, dict + ] = None, + *, + customer_id: str = None, + conversions: Sequence[conversion_upload_service.CallConversion] = None, + partial_failure: bool = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_upload_service.UploadCallConversionsResponse: + r"""Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.UploadCallConversionsRequest, dict]): + The request object. Request message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadCallConversions]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (Sequence[google.ads.googleads.v12.services.types.CallConversion]): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.UploadCallConversionsResponse: + Response message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadCallConversions]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, conversions, partial_failure]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_upload_service.UploadCallConversionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, conversion_upload_service.UploadCallConversionsRequest + ): + request = conversion_upload_service.UploadCallConversionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversions is not None: + request.conversions = conversions + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_call_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionUploadServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_upload_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/__init__.py new file mode 100644 index 000000000..3a10381ba --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionUploadServiceTransport +from .grpc import ConversionUploadServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionUploadServiceTransport]] +_transport_registry["grpc"] = ConversionUploadServiceGrpcTransport + +__all__ = ( + "ConversionUploadServiceTransport", + "ConversionUploadServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_upload_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/base.py new file mode 100644 index 000000000..ff2355619 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/base.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import conversion_upload_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionUploadServiceTransport(abc.ABC): + """Abstract transport class for ConversionUploadService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_click_conversions: gapic_v1.method.wrap_method( + self.upload_click_conversions, + default_timeout=None, + client_info=client_info, + ), + self.upload_call_conversions: gapic_v1.method.wrap_method( + self.upload_call_conversions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_click_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadClickConversionsRequest], + Union[ + conversion_upload_service.UploadClickConversionsResponse, + Awaitable[conversion_upload_service.UploadClickConversionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def upload_call_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadCallConversionsRequest], + Union[ + conversion_upload_service.UploadCallConversionsResponse, + Awaitable[conversion_upload_service.UploadCallConversionsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionUploadServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_upload_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/grpc.py new file mode 100644 index 000000000..3137997ee --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_upload_service/transports/grpc.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import conversion_upload_service +from .base import ConversionUploadServiceTransport, DEFAULT_CLIENT_INFO + + +class ConversionUploadServiceGrpcTransport(ConversionUploadServiceTransport): + """gRPC backend transport for ConversionUploadService. + + Service to upload conversions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def upload_click_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadClickConversionsRequest], + conversion_upload_service.UploadClickConversionsResponse, + ]: + r"""Return a callable for the upload click conversions method over gRPC. + + Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadClickConversionsRequest], + ~.UploadClickConversionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_click_conversions" not in self._stubs: + self._stubs[ + "upload_click_conversions" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionUploadService/UploadClickConversions", + request_serializer=conversion_upload_service.UploadClickConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadClickConversionsResponse.deserialize, + ) + return self._stubs["upload_click_conversions"] + + @property + def upload_call_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadCallConversionsRequest], + conversion_upload_service.UploadCallConversionsResponse, + ]: + r"""Return a callable for the upload call conversions method over gRPC. + + Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadCallConversionsRequest], + ~.UploadCallConversionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_call_conversions" not in self._stubs: + self._stubs[ + "upload_call_conversions" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionUploadService/UploadCallConversions", + request_serializer=conversion_upload_service.UploadCallConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadCallConversionsResponse.deserialize, + ) + return self._stubs["upload_call_conversions"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_value_rule_service/__init__.py new file mode 100644 index 000000000..c30b50e20 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionValueRuleServiceClient + +__all__ = ("ConversionValueRuleServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_service/client.py b/google/ads/googleads/v12/services/services/conversion_value_rule_service/client.py new file mode 100644 index 000000000..1da198deb --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_service/client.py @@ -0,0 +1,555 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionValueRuleServiceGrpcTransport + + +class ConversionValueRuleServiceClientMeta(type): + """Metaclass for the ConversionValueRuleService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionValueRuleServiceTransport]] + _transport_registry["grpc"] = ConversionValueRuleServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionValueRuleServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionValueRuleServiceClient( + metaclass=ConversionValueRuleServiceClientMeta +): + """Service to manage conversion value rules.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionValueRuleServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_value_rule_path( + customer_id: str, conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path(customer_id: str, user_interest_id: str,) -> str: + """Returns a fully-qualified user_interest string.""" + return "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, user_interest_id=user_interest_id, + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path(customer_id: str, user_list_id: str,) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ConversionValueRuleServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionValueRuleServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionValueRuleServiceTransport): + # transport is a ConversionValueRuleServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_conversion_value_rules( + self, + request: Union[ + conversion_value_rule_service.MutateConversionValueRulesRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + conversion_value_rule_service.ConversionValueRuleOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_value_rule_service.MutateConversionValueRulesResponse: + r"""Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateConversionValueRulesRequest, dict]): + The request object. Request message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v12.services.ConversionValueRuleService.MutateConversionValueRules]. + customer_id (str): + Required. The ID of the customer + whose conversion value rules are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionValueRuleOperation]): + Required. The list of operations to + perform on individual conversion value + rules. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateConversionValueRulesResponse: + Response message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v12.services.ConversionValueRuleService.MutateConversionValueRules]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_value_rule_service.MutateConversionValueRulesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + conversion_value_rule_service.MutateConversionValueRulesRequest, + ): + request = conversion_value_rule_service.MutateConversionValueRulesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_value_rules + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionValueRuleServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/__init__.py new file mode 100644 index 000000000..dcd66a8e1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionValueRuleServiceTransport +from .grpc import ConversionValueRuleServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionValueRuleServiceTransport]] +_transport_registry["grpc"] = ConversionValueRuleServiceGrpcTransport + +__all__ = ( + "ConversionValueRuleServiceTransport", + "ConversionValueRuleServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/base.py new file mode 100644 index 000000000..843036c72 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionValueRuleServiceTransport(abc.ABC): + """Abstract transport class for ConversionValueRuleService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_value_rules: gapic_v1.method.wrap_method( + self.mutate_conversion_value_rules, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_value_rules( + self, + ) -> Callable[ + [conversion_value_rule_service.MutateConversionValueRulesRequest], + Union[ + conversion_value_rule_service.MutateConversionValueRulesResponse, + Awaitable[ + conversion_value_rule_service.MutateConversionValueRulesResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionValueRuleServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/grpc.py new file mode 100644 index 000000000..444f5106f --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_service, +) +from .base import ConversionValueRuleServiceTransport, DEFAULT_CLIENT_INFO + + +class ConversionValueRuleServiceGrpcTransport( + ConversionValueRuleServiceTransport +): + """gRPC backend transport for ConversionValueRuleService. + + Service to manage conversion value rules. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_conversion_value_rules( + self, + ) -> Callable[ + [conversion_value_rule_service.MutateConversionValueRulesRequest], + conversion_value_rule_service.MutateConversionValueRulesResponse, + ]: + r"""Return a callable for the mutate conversion value rules method over gRPC. + + Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRulesRequest], + ~.MutateConversionValueRulesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rules" not in self._stubs: + self._stubs[ + "mutate_conversion_value_rules" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionValueRuleService/MutateConversionValueRules", + request_serializer=conversion_value_rule_service.MutateConversionValueRulesRequest.serialize, + response_deserializer=conversion_value_rule_service.MutateConversionValueRulesResponse.deserialize, + ) + return self._stubs["mutate_conversion_value_rules"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionValueRuleServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/__init__.py b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/__init__.py new file mode 100644 index 000000000..51ec19bc9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ConversionValueRuleSetServiceClient + +__all__ = ("ConversionValueRuleSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/client.py b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/client.py new file mode 100644 index 000000000..025f8d69c --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/client.py @@ -0,0 +1,547 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_set_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionValueRuleSetServiceGrpcTransport + + +class ConversionValueRuleSetServiceClientMeta(type): + """Metaclass for the ConversionValueRuleSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionValueRuleSetServiceTransport]] + _transport_registry["grpc"] = ConversionValueRuleSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ConversionValueRuleSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionValueRuleSetServiceClient( + metaclass=ConversionValueRuleSetServiceClientMeta +): + """Service to manage conversion value rule sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionValueRuleSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, ConversionValueRuleSetServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ConversionValueRuleSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ConversionValueRuleSetServiceTransport): + # transport is a ConversionValueRuleSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_conversion_value_rule_sets( + self, + request: Union[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + conversion_value_rule_set_service.ConversionValueRuleSetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse: + r"""Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateConversionValueRuleSetsRequest, dict]): + The request object. Request message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v12.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + customer_id (str): + Required. The ID of the customer + whose conversion value rule sets are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionValueRuleSetOperation]): + Required. The list of operations to + perform on individual conversion value + rule sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateConversionValueRuleSetsResponse: + Response message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v12.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + ): + request = conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_value_rule_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ConversionValueRuleSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/__init__.py new file mode 100644 index 000000000..4ead9c533 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ConversionValueRuleSetServiceTransport +from .grpc import ConversionValueRuleSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ConversionValueRuleSetServiceTransport]] +_transport_registry["grpc"] = ConversionValueRuleSetServiceGrpcTransport + +__all__ = ( + "ConversionValueRuleSetServiceTransport", + "ConversionValueRuleSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/base.py b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/base.py new file mode 100644 index 000000000..4d2a79075 --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_set_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ConversionValueRuleSetServiceTransport(abc.ABC): + """Abstract transport class for ConversionValueRuleSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_value_rule_sets: gapic_v1.method.wrap_method( + self.mutate_conversion_value_rule_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_value_rule_sets( + self, + ) -> Callable[ + [ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest + ], + Union[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, + Awaitable[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ConversionValueRuleSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/grpc.py new file mode 100644 index 000000000..c9a39f47b --- /dev/null +++ b/google/ads/googleads/v12/services/services/conversion_value_rule_set_service/transports/grpc.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_set_service, +) +from .base import ConversionValueRuleSetServiceTransport, DEFAULT_CLIENT_INFO + + +class ConversionValueRuleSetServiceGrpcTransport( + ConversionValueRuleSetServiceTransport +): + """gRPC backend transport for ConversionValueRuleSetService. + + Service to manage conversion value rule sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_conversion_value_rule_sets( + self, + ) -> Callable[ + [ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest + ], + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, + ]: + r"""Return a callable for the mutate conversion value rule + sets method over gRPC. + + Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRuleSetsRequest], + ~.MutateConversionValueRuleSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rule_sets" not in self._stubs: + self._stubs[ + "mutate_conversion_value_rule_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ConversionValueRuleSetService/MutateConversionValueRuleSets", + request_serializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest.serialize, + response_deserializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse.deserialize, + ) + return self._stubs["mutate_conversion_value_rule_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ConversionValueRuleSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_audience_service/__init__.py b/google/ads/googleads/v12/services/services/custom_audience_service/__init__.py new file mode 100644 index 000000000..d751855af --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_audience_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomAudienceServiceClient + +__all__ = ("CustomAudienceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_audience_service/client.py b/google/ads/googleads/v12/services/services/custom_audience_service/client.py new file mode 100644 index 000000000..0b58c8056 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_audience_service/client.py @@ -0,0 +1,493 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import custom_audience_service +from .transports.base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomAudienceServiceGrpcTransport + + +class CustomAudienceServiceClientMeta(type): + """Metaclass for the CustomAudienceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomAudienceServiceTransport]] + _transport_registry["grpc"] = CustomAudienceServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomAudienceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomAudienceServiceClient(metaclass=CustomAudienceServiceClientMeta): + """Service to manage custom audiences.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomAudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomAudienceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def custom_audience_path(customer_id: str, custom_audience_id: str,) -> str: + """Returns a fully-qualified custom_audience string.""" + return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( + customer_id=customer_id, custom_audience_id=custom_audience_id, + ) + + @staticmethod + def parse_custom_audience_path(path: str) -> Dict[str, str]: + """Parses a custom_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomAudienceServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom audience service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomAudienceServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomAudienceServiceTransport): + # transport is a CustomAudienceServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_custom_audiences( + self, + request: Union[ + custom_audience_service.MutateCustomAudiencesRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + custom_audience_service.CustomAudienceOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> custom_audience_service.MutateCustomAudiencesResponse: + r"""Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomAudiencesRequest, dict]): + The request object. Request message for + [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v12.services.CustomAudienceService.MutateCustomAudiences]. + customer_id (str): + Required. The ID of the customer + whose custom audiences are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomAudienceOperation]): + Required. The list of operations to + perform on individual custom audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomAudiencesResponse: + Response message for custom audience + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a custom_audience_service.MutateCustomAudiencesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, custom_audience_service.MutateCustomAudiencesRequest + ): + request = custom_audience_service.MutateCustomAudiencesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_audiences + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomAudienceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_audience_service/transports/__init__.py b/google/ads/googleads/v12/services/services/custom_audience_service/transports/__init__.py new file mode 100644 index 000000000..81f1c73bc --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_audience_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomAudienceServiceTransport +from .grpc import CustomAudienceServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomAudienceServiceTransport]] +_transport_registry["grpc"] = CustomAudienceServiceGrpcTransport + +__all__ = ( + "CustomAudienceServiceTransport", + "CustomAudienceServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/custom_audience_service/transports/base.py b/google/ads/googleads/v12/services/services/custom_audience_service/transports/base.py new file mode 100644 index 000000000..2239737b2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_audience_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import custom_audience_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomAudienceServiceTransport(abc.ABC): + """Abstract transport class for CustomAudienceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_audiences: gapic_v1.method.wrap_method( + self.mutate_custom_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_audiences( + self, + ) -> Callable[ + [custom_audience_service.MutateCustomAudiencesRequest], + Union[ + custom_audience_service.MutateCustomAudiencesResponse, + Awaitable[custom_audience_service.MutateCustomAudiencesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomAudienceServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_audience_service/transports/grpc.py b/google/ads/googleads/v12/services/services/custom_audience_service/transports/grpc.py new file mode 100644 index 000000000..d157b68a7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_audience_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import custom_audience_service +from .base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomAudienceServiceGrpcTransport(CustomAudienceServiceTransport): + """gRPC backend transport for CustomAudienceService. + + Service to manage custom audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_custom_audiences( + self, + ) -> Callable[ + [custom_audience_service.MutateCustomAudiencesRequest], + custom_audience_service.MutateCustomAudiencesResponse, + ]: + r"""Return a callable for the mutate custom audiences method over gRPC. + + Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomAudiencesRequest], + ~.MutateCustomAudiencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_audiences" not in self._stubs: + self._stubs[ + "mutate_custom_audiences" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomAudienceService/MutateCustomAudiences", + request_serializer=custom_audience_service.MutateCustomAudiencesRequest.serialize, + response_deserializer=custom_audience_service.MutateCustomAudiencesResponse.deserialize, + ) + return self._stubs["mutate_custom_audiences"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomAudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_conversion_goal_service/__init__.py b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/__init__.py new file mode 100644 index 000000000..85946bef5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomConversionGoalServiceClient + +__all__ = ("CustomConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_conversion_goal_service/client.py b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/client.py new file mode 100644 index 000000000..ae5275f7f --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/client.py @@ -0,0 +1,515 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + custom_conversion_goal_service, +) +from .transports.base import ( + CustomConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomConversionGoalServiceGrpcTransport + + +class CustomConversionGoalServiceClientMeta(type): + """Metaclass for the CustomConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomConversionGoalServiceTransport]] + _transport_registry["grpc"] = CustomConversionGoalServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomConversionGoalServiceClient( + metaclass=CustomConversionGoalServiceClientMeta +): + """Service to manage custom conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path(customer_id: str, goal_id: str,) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CustomConversionGoalServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomConversionGoalServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomConversionGoalServiceTransport): + # transport is a CustomConversionGoalServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_custom_conversion_goals( + self, + request: Union[ + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + custom_conversion_goal_service.CustomConversionGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> custom_conversion_goal_service.MutateCustomConversionGoalsResponse: + r"""Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomConversionGoalsRequest, dict]): + The request object. Request message for + [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v12.services.CustomConversionGoalService.MutateCustomConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomConversionGoalOperation]): + Required. The list of operations to + perform on individual custom conversion + goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomConversionGoalsResponse: + Response message for a custom + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a custom_conversion_goal_service.MutateCustomConversionGoalsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + ): + request = custom_conversion_goal_service.MutateCustomConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/__init__.py new file mode 100644 index 000000000..8f304ec37 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomConversionGoalServiceTransport +from .grpc import CustomConversionGoalServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomConversionGoalServiceTransport]] +_transport_registry["grpc"] = CustomConversionGoalServiceGrpcTransport + +__all__ = ( + "CustomConversionGoalServiceTransport", + "CustomConversionGoalServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/base.py b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..ce3a81a8d --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + custom_conversion_goal_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CustomConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_custom_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_conversion_goals( + self, + ) -> Callable[ + [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], + Union[ + custom_conversion_goal_service.MutateCustomConversionGoalsResponse, + Awaitable[ + custom_conversion_goal_service.MutateCustomConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..ade2e0551 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_conversion_goal_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + custom_conversion_goal_service, +) +from .base import CustomConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomConversionGoalServiceGrpcTransport( + CustomConversionGoalServiceTransport +): + """gRPC backend transport for CustomConversionGoalService. + + Service to manage custom conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_custom_conversion_goals( + self, + ) -> Callable[ + [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], + custom_conversion_goal_service.MutateCustomConversionGoalsResponse, + ]: + r"""Return a callable for the mutate custom conversion goals method over gRPC. + + Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomConversionGoalsRequest], + ~.MutateCustomConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_conversion_goals" not in self._stubs: + self._stubs[ + "mutate_custom_conversion_goals" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomConversionGoalService/MutateCustomConversionGoals", + request_serializer=custom_conversion_goal_service.MutateCustomConversionGoalsRequest.serialize, + response_deserializer=custom_conversion_goal_service.MutateCustomConversionGoalsResponse.deserialize, + ) + return self._stubs["mutate_custom_conversion_goals"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_interest_service/__init__.py b/google/ads/googleads/v12/services/services/custom_interest_service/__init__.py new file mode 100644 index 000000000..d6225ccac --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_interest_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomInterestServiceClient + +__all__ = ("CustomInterestServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_interest_service/client.py b/google/ads/googleads/v12/services/services/custom_interest_service/client.py new file mode 100644 index 000000000..f5fdfe3e0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_interest_service/client.py @@ -0,0 +1,492 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import custom_interest_service +from .transports.base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomInterestServiceGrpcTransport + + +class CustomInterestServiceClientMeta(type): + """Metaclass for the CustomInterestService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomInterestServiceTransport]] + _transport_registry["grpc"] = CustomInterestServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomInterestServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomInterestServiceClient(metaclass=CustomInterestServiceClientMeta): + """Service to manage custom interests.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomInterestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomInterestServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def custom_interest_path(customer_id: str, custom_interest_id: str,) -> str: + """Returns a fully-qualified custom_interest string.""" + return "customers/{customer_id}/customInterests/{custom_interest_id}".format( + customer_id=customer_id, custom_interest_id=custom_interest_id, + ) + + @staticmethod + def parse_custom_interest_path(path: str) -> Dict[str, str]: + """Parses a custom_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomInterestServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom interest service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomInterestServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomInterestServiceTransport): + # transport is a CustomInterestServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_custom_interests( + self, + request: Union[ + custom_interest_service.MutateCustomInterestsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + custom_interest_service.CustomInterestOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> custom_interest_service.MutateCustomInterestsResponse: + r"""Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomInterestsRequest, dict]): + The request object. Request message for + [CustomInterestService.MutateCustomInterests][google.ads.googleads.v12.services.CustomInterestService.MutateCustomInterests]. + customer_id (str): + Required. The ID of the customer + whose custom interests are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomInterestOperation]): + Required. The list of operations to + perform on individual custom interests. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomInterestsResponse: + Response message for custom interest + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a custom_interest_service.MutateCustomInterestsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, custom_interest_service.MutateCustomInterestsRequest + ): + request = custom_interest_service.MutateCustomInterestsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_interests + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomInterestServiceClient",) diff --git a/google/ads/googleads/v12/services/services/custom_interest_service/transports/__init__.py b/google/ads/googleads/v12/services/services/custom_interest_service/transports/__init__.py new file mode 100644 index 000000000..fe9503a50 --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_interest_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomInterestServiceTransport +from .grpc import CustomInterestServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomInterestServiceTransport]] +_transport_registry["grpc"] = CustomInterestServiceGrpcTransport + +__all__ = ( + "CustomInterestServiceTransport", + "CustomInterestServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/custom_interest_service/transports/base.py b/google/ads/googleads/v12/services/services/custom_interest_service/transports/base.py new file mode 100644 index 000000000..8da59a3bb --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_interest_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import custom_interest_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomInterestServiceTransport(abc.ABC): + """Abstract transport class for CustomInterestService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_interests: gapic_v1.method.wrap_method( + self.mutate_custom_interests, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_interests( + self, + ) -> Callable[ + [custom_interest_service.MutateCustomInterestsRequest], + Union[ + custom_interest_service.MutateCustomInterestsResponse, + Awaitable[custom_interest_service.MutateCustomInterestsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomInterestServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/custom_interest_service/transports/grpc.py b/google/ads/googleads/v12/services/services/custom_interest_service/transports/grpc.py new file mode 100644 index 000000000..ebc0700be --- /dev/null +++ b/google/ads/googleads/v12/services/services/custom_interest_service/transports/grpc.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import custom_interest_service +from .base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomInterestServiceGrpcTransport(CustomInterestServiceTransport): + """gRPC backend transport for CustomInterestService. + + Service to manage custom interests. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_custom_interests( + self, + ) -> Callable[ + [custom_interest_service.MutateCustomInterestsRequest], + custom_interest_service.MutateCustomInterestsResponse, + ]: + r"""Return a callable for the mutate custom interests method over gRPC. + + Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCustomInterestsRequest], + ~.MutateCustomInterestsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_interests" not in self._stubs: + self._stubs[ + "mutate_custom_interests" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomInterestService/MutateCustomInterests", + request_serializer=custom_interest_service.MutateCustomInterestsRequest.serialize, + response_deserializer=custom_interest_service.MutateCustomInterestsResponse.deserialize, + ) + return self._stubs["mutate_custom_interests"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomInterestServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_service/__init__.py b/google/ads/googleads/v12/services/services/customer_asset_service/__init__.py new file mode 100644 index 000000000..592ad9cd0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerAssetServiceClient + +__all__ = ("CustomerAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_service/client.py b/google/ads/googleads/v12/services/services/customer_asset_service/client.py new file mode 100644 index 000000000..f5e29f10a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_service/client.py @@ -0,0 +1,508 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerAssetServiceGrpcTransport + + +class CustomerAssetServiceClientMeta(type): + """Metaclass for the CustomerAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerAssetServiceTransport]] + _transport_registry["grpc"] = CustomerAssetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerAssetServiceClient(metaclass=CustomerAssetServiceClientMeta): + """Service to manage customer assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, asset_id=asset_id, field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerAssetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerAssetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerAssetServiceTransport): + # transport is a CustomerAssetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_assets( + self, + request: Union[ + customer_asset_service.MutateCustomerAssetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_asset_service.CustomerAssetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_asset_service.MutateCustomerAssetsResponse: + r"""Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerAssetsRequest, dict]): + The request object. Request message for + [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v12.services.CustomerAssetService.MutateCustomerAssets]. + customer_id (str): + Required. The ID of the customer + whose customer assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerAssetOperation]): + Required. The list of operations to + perform on individual customer assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerAssetsResponse: + Response message for a customer asset + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_asset_service.MutateCustomerAssetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_asset_service.MutateCustomerAssetsRequest + ): + request = customer_asset_service.MutateCustomerAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerAssetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_asset_service/transports/__init__.py new file mode 100644 index 000000000..65e80a0a8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerAssetServiceTransport +from .grpc import CustomerAssetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerAssetServiceTransport]] +_transport_registry["grpc"] = CustomerAssetServiceGrpcTransport + +__all__ = ( + "CustomerAssetServiceTransport", + "CustomerAssetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_asset_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_asset_service/transports/base.py new file mode 100644 index 000000000..ee228c44f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerAssetServiceTransport(abc.ABC): + """Abstract transport class for CustomerAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_assets: gapic_v1.method.wrap_method( + self.mutate_customer_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_assets( + self, + ) -> Callable[ + [customer_asset_service.MutateCustomerAssetsRequest], + Union[ + customer_asset_service.MutateCustomerAssetsResponse, + Awaitable[customer_asset_service.MutateCustomerAssetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerAssetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_asset_service/transports/grpc.py new file mode 100644 index 000000000..413bdb987 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_service +from .base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerAssetServiceGrpcTransport(CustomerAssetServiceTransport): + """gRPC backend transport for CustomerAssetService. + + Service to manage customer assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_assets( + self, + ) -> Callable[ + [customer_asset_service.MutateCustomerAssetsRequest], + customer_asset_service.MutateCustomerAssetsResponse, + ]: + r"""Return a callable for the mutate customer assets method over gRPC. + + Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerAssetsRequest], + ~.MutateCustomerAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_assets" not in self._stubs: + self._stubs[ + "mutate_customer_assets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerAssetService/MutateCustomerAssets", + request_serializer=customer_asset_service.MutateCustomerAssetsRequest.serialize, + response_deserializer=customer_asset_service.MutateCustomerAssetsResponse.deserialize, + ) + return self._stubs["mutate_customer_assets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_set_service/__init__.py b/google/ads/googleads/v12/services/services/customer_asset_set_service/__init__.py new file mode 100644 index 000000000..423f121e6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerAssetSetServiceClient + +__all__ = ("CustomerAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_set_service/client.py b/google/ads/googleads/v12/services/services/customer_asset_set_service/client.py new file mode 100644 index 000000000..c2e5168f1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_set_service/client.py @@ -0,0 +1,519 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerAssetSetServiceGrpcTransport + + +class CustomerAssetSetServiceClientMeta(type): + """Metaclass for the CustomerAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerAssetSetServiceTransport]] + _transport_registry["grpc"] = CustomerAssetSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerAssetSetServiceClient( + metaclass=CustomerAssetSetServiceClientMeta +): + """Service to manage customer asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified customer_asset_set string.""" + return "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_customer_asset_set_path(path: str) -> Dict[str, str]: + """Parses a customer_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerAssetSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerAssetSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerAssetSetServiceTransport): + # transport is a CustomerAssetSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_asset_sets( + self, + request: Union[ + customer_asset_set_service.MutateCustomerAssetSetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_asset_set_service.CustomerAssetSetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_asset_set_service.MutateCustomerAssetSetsResponse: + r"""Creates, or removes customer asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerAssetSetsRequest, dict]): + The request object. Request message for + [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v12.services.CustomerAssetSetService.MutateCustomerAssetSets]. + customer_id (str): + Required. The ID of the customer + whose customer asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerAssetSetOperation]): + Required. The list of operations to + perform on individual customer asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerAssetSetsResponse: + Response message for a customer asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_asset_set_service.MutateCustomerAssetSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_asset_set_service.MutateCustomerAssetSetsRequest + ): + request = customer_asset_set_service.MutateCustomerAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerAssetSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/__init__.py new file mode 100644 index 000000000..779181d43 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerAssetSetServiceTransport +from .grpc import CustomerAssetSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerAssetSetServiceTransport]] +_transport_registry["grpc"] = CustomerAssetSetServiceGrpcTransport + +__all__ = ( + "CustomerAssetSetServiceTransport", + "CustomerAssetSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/base.py new file mode 100644 index 000000000..1e5c954e3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerAssetSetServiceTransport(abc.ABC): + """Abstract transport class for CustomerAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_asset_sets: gapic_v1.method.wrap_method( + self.mutate_customer_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_asset_sets( + self, + ) -> Callable[ + [customer_asset_set_service.MutateCustomerAssetSetsRequest], + Union[ + customer_asset_set_service.MutateCustomerAssetSetsResponse, + Awaitable[ + customer_asset_set_service.MutateCustomerAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerAssetSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..43a9b0044 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_asset_set_service/transports/grpc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_asset_set_service +from .base import CustomerAssetSetServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerAssetSetServiceGrpcTransport(CustomerAssetSetServiceTransport): + """gRPC backend transport for CustomerAssetSetService. + + Service to manage customer asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_asset_sets( + self, + ) -> Callable[ + [customer_asset_set_service.MutateCustomerAssetSetsRequest], + customer_asset_set_service.MutateCustomerAssetSetsResponse, + ]: + r"""Return a callable for the mutate customer asset sets method over gRPC. + + Creates, or removes customer asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateCustomerAssetSetsRequest], + ~.MutateCustomerAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_asset_sets" not in self._stubs: + self._stubs[ + "mutate_customer_asset_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerAssetSetService/MutateCustomerAssetSets", + request_serializer=customer_asset_set_service.MutateCustomerAssetSetsRequest.serialize, + response_deserializer=customer_asset_set_service.MutateCustomerAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_customer_asset_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_client_link_service/__init__.py b/google/ads/googleads/v12/services/services/customer_client_link_service/__init__.py new file mode 100644 index 000000000..0161b3b0a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_client_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerClientLinkServiceClient + +__all__ = ("CustomerClientLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_client_link_service/client.py b/google/ads/googleads/v12/services/services/customer_client_link_service/client.py new file mode 100644 index 000000000..73f7ec9b8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_client_link_service/client.py @@ -0,0 +1,510 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_client_link_service +from .transports.base import ( + CustomerClientLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerClientLinkServiceGrpcTransport + + +class CustomerClientLinkServiceClientMeta(type): + """Metaclass for the CustomerClientLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerClientLinkServiceTransport]] + _transport_registry["grpc"] = CustomerClientLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerClientLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerClientLinkServiceClient( + metaclass=CustomerClientLinkServiceClientMeta +): + """Service to manage customer client links.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerClientLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerClientLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_link_path( + customer_id: str, client_customer_id: str, manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_client_link string.""" + return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + client_customer_id=client_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_client_link_path(path: str) -> Dict[str, str]: + """Parses a customer_client_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerClientLinkServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer client link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerClientLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerClientLinkServiceTransport): + # transport is a CustomerClientLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_client_link( + self, + request: Union[ + customer_client_link_service.MutateCustomerClientLinkRequest, dict + ] = None, + *, + customer_id: str = None, + operation: customer_client_link_service.CustomerClientLinkOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_client_link_service.MutateCustomerClientLinkResponse: + r"""Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerClientLinkRequest, dict]): + The request object. Request message for + [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v12.services.CustomerClientLinkService.MutateCustomerClientLink]. + customer_id (str): + Required. The ID of the customer + whose customer link are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.CustomerClientLinkOperation): + Required. The operation to perform on + the individual CustomerClientLink. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerClientLinkResponse: + Response message for a + CustomerClientLink mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_client_link_service.MutateCustomerClientLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_client_link_service.MutateCustomerClientLinkRequest, + ): + request = customer_client_link_service.MutateCustomerClientLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_client_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerClientLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_client_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/__init__.py new file mode 100644 index 000000000..2f933ad78 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerClientLinkServiceTransport +from .grpc import CustomerClientLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerClientLinkServiceTransport]] +_transport_registry["grpc"] = CustomerClientLinkServiceGrpcTransport + +__all__ = ( + "CustomerClientLinkServiceTransport", + "CustomerClientLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_client_link_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/base.py new file mode 100644 index 000000000..852d37a41 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_client_link_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerClientLinkServiceTransport(abc.ABC): + """Abstract transport class for CustomerClientLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_client_link: gapic_v1.method.wrap_method( + self.mutate_customer_client_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_client_link( + self, + ) -> Callable[ + [customer_client_link_service.MutateCustomerClientLinkRequest], + Union[ + customer_client_link_service.MutateCustomerClientLinkResponse, + Awaitable[ + customer_client_link_service.MutateCustomerClientLinkResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerClientLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_client_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/grpc.py new file mode 100644 index 000000000..3d70df1a9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_client_link_service/transports/grpc.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_client_link_service +from .base import CustomerClientLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerClientLinkServiceGrpcTransport( + CustomerClientLinkServiceTransport +): + """gRPC backend transport for CustomerClientLinkService. + + Service to manage customer client links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_client_link( + self, + ) -> Callable[ + [customer_client_link_service.MutateCustomerClientLinkRequest], + customer_client_link_service.MutateCustomerClientLinkResponse, + ]: + r"""Return a callable for the mutate customer client link method over gRPC. + + Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerClientLinkRequest], + ~.MutateCustomerClientLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_client_link" not in self._stubs: + self._stubs[ + "mutate_customer_client_link" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerClientLinkService/MutateCustomerClientLink", + request_serializer=customer_client_link_service.MutateCustomerClientLinkRequest.serialize, + response_deserializer=customer_client_link_service.MutateCustomerClientLinkResponse.deserialize, + ) + return self._stubs["mutate_customer_client_link"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerClientLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_conversion_goal_service/__init__.py b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/__init__.py new file mode 100644 index 000000000..14de2e1d2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerConversionGoalServiceClient + +__all__ = ("CustomerConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_conversion_goal_service/client.py b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/client.py new file mode 100644 index 000000000..2a5acc8f5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/client.py @@ -0,0 +1,499 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_conversion_goal_service, +) +from .transports.base import ( + CustomerConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerConversionGoalServiceGrpcTransport + + +class CustomerConversionGoalServiceClientMeta(type): + """Metaclass for the CustomerConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerConversionGoalServiceTransport]] + _transport_registry["grpc"] = CustomerConversionGoalServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerConversionGoalServiceClient( + metaclass=CustomerConversionGoalServiceClientMeta +): + """Service to manage customer conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, category=category, source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CustomerConversionGoalServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerConversionGoalServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerConversionGoalServiceTransport): + # transport is a CustomerConversionGoalServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_conversion_goals( + self, + request: Union[ + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_conversion_goal_service.CustomerConversionGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_conversion_goal_service.MutateCustomerConversionGoalsResponse: + r"""Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerConversionGoalsRequest, dict]): + The request object. Request message for + [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v12.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose customer conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerConversionGoalOperation]): + Required. The list of operations to + perform on individual customer + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerConversionGoalsResponse: + Response message for a customer + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_conversion_goal_service.MutateCustomerConversionGoalsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + ): + request = customer_conversion_goal_service.MutateCustomerConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerConversionGoalServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/__init__.py new file mode 100644 index 000000000..b196c3278 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerConversionGoalServiceTransport +from .grpc import CustomerConversionGoalServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerConversionGoalServiceTransport]] +_transport_registry["grpc"] = CustomerConversionGoalServiceGrpcTransport + +__all__ = ( + "CustomerConversionGoalServiceTransport", + "CustomerConversionGoalServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..7409a3896 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_conversion_goal_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CustomerConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_customer_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_conversion_goals( + self, + ) -> Callable[ + [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], + Union[ + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, + Awaitable[ + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..5ac5c9445 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_conversion_goal_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_conversion_goal_service, +) +from .base import CustomerConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerConversionGoalServiceGrpcTransport( + CustomerConversionGoalServiceTransport +): + """gRPC backend transport for CustomerConversionGoalService. + + Service to manage customer conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_conversion_goals( + self, + ) -> Callable[ + [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, + ]: + r"""Return a callable for the mutate customer conversion + goals method over gRPC. + + Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerConversionGoalsRequest], + ~.MutateCustomerConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_conversion_goals" not in self._stubs: + self._stubs[ + "mutate_customer_conversion_goals" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerConversionGoalService/MutateCustomerConversionGoals", + request_serializer=customer_conversion_goal_service.MutateCustomerConversionGoalsRequest.serialize, + response_deserializer=customer_conversion_goal_service.MutateCustomerConversionGoalsResponse.deserialize, + ) + return self._stubs["mutate_customer_conversion_goals"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_customizer_service/__init__.py b/google/ads/googleads/v12/services/services/customer_customizer_service/__init__.py new file mode 100644 index 000000000..61621f91b --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_customizer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerCustomizerServiceClient + +__all__ = ("CustomerCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_customizer_service/client.py b/google/ads/googleads/v12/services/services/customer_customizer_service/client.py new file mode 100644 index 000000000..3de7ed825 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_customizer_service/client.py @@ -0,0 +1,515 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerCustomizerServiceGrpcTransport + + +class CustomerCustomizerServiceClientMeta(type): + """Metaclass for the CustomerCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerCustomizerServiceTransport]] + _transport_registry["grpc"] = CustomerCustomizerServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerCustomizerServiceClient( + metaclass=CustomerCustomizerServiceClientMeta +): + """Service to manage customer customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_customizer_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerCustomizerServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerCustomizerServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerCustomizerServiceTransport): + # transport is a CustomerCustomizerServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_customizers( + self, + request: Union[ + customer_customizer_service.MutateCustomerCustomizersRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_customizer_service.CustomerCustomizerOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_customizer_service.MutateCustomerCustomizersResponse: + r"""Creates, updates or removes customer customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerCustomizersRequest, dict]): + The request object. Request message for + [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v12.services.CustomerCustomizerService.MutateCustomerCustomizers]. + customer_id (str): + Required. The ID of the customer + whose customer customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerCustomizerOperation]): + Required. The list of operations to + perform on individual customer + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerCustomizersResponse: + Response message for an customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_customizer_service.MutateCustomerCustomizersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_customizer_service.MutateCustomerCustomizersRequest, + ): + request = customer_customizer_service.MutateCustomerCustomizersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerCustomizerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_customizer_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/__init__.py new file mode 100644 index 000000000..323aab758 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerCustomizerServiceTransport +from .grpc import CustomerCustomizerServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerCustomizerServiceTransport]] +_transport_registry["grpc"] = CustomerCustomizerServiceGrpcTransport + +__all__ = ( + "CustomerCustomizerServiceTransport", + "CustomerCustomizerServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_customizer_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/base.py new file mode 100644 index 000000000..373db087c --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_customizer_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerCustomizerServiceTransport(abc.ABC): + """Abstract transport class for CustomerCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_customizers: gapic_v1.method.wrap_method( + self.mutate_customer_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_customizers( + self, + ) -> Callable[ + [customer_customizer_service.MutateCustomerCustomizersRequest], + Union[ + customer_customizer_service.MutateCustomerCustomizersResponse, + Awaitable[ + customer_customizer_service.MutateCustomerCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerCustomizerServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_customizer_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/grpc.py new file mode 100644 index 000000000..7cdd5eb28 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_customizer_service/transports/grpc.py @@ -0,0 +1,273 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_customizer_service +from .base import CustomerCustomizerServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerCustomizerServiceGrpcTransport( + CustomerCustomizerServiceTransport +): + """gRPC backend transport for CustomerCustomizerService. + + Service to manage customer customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_customizers( + self, + ) -> Callable[ + [customer_customizer_service.MutateCustomerCustomizersRequest], + customer_customizer_service.MutateCustomerCustomizersResponse, + ]: + r"""Return a callable for the mutate customer customizers method over gRPC. + + Creates, updates or removes customer customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerCustomizersRequest], + ~.MutateCustomerCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_customizers" not in self._stubs: + self._stubs[ + "mutate_customer_customizers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerCustomizerService/MutateCustomerCustomizers", + request_serializer=customer_customizer_service.MutateCustomerCustomizersRequest.serialize, + response_deserializer=customer_customizer_service.MutateCustomerCustomizersResponse.deserialize, + ) + return self._stubs["mutate_customer_customizers"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_extension_setting_service/__init__.py b/google/ads/googleads/v12/services/services/customer_extension_setting_service/__init__.py new file mode 100644 index 000000000..2ed401b65 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_extension_setting_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerExtensionSettingServiceClient + +__all__ = ("CustomerExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_extension_setting_service/client.py b/google/ads/googleads/v12/services/services/customer_extension_setting_service/client.py new file mode 100644 index 000000000..d8997fbcf --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_extension_setting_service/client.py @@ -0,0 +1,528 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_extension_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerExtensionSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerExtensionSettingServiceGrpcTransport + + +class CustomerExtensionSettingServiceClientMeta(type): + """Metaclass for the CustomerExtensionSettingService 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[CustomerExtensionSettingServiceTransport]] + _transport_registry["grpc"] = CustomerExtensionSettingServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerExtensionSettingServiceTransport]: + """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 CustomerExtensionSettingServiceClient( + metaclass=CustomerExtensionSettingServiceClientMeta +): + """Service to manage customer extension settings.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerExtensionSettingServiceClient: 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: + CustomerExtensionSettingServiceClient: 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) -> CustomerExtensionSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerExtensionSettingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_extension_setting_path( + customer_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified customer_extension_setting string.""" + return "customers/{customer_id}/customerExtensionSettings/{extension_type}".format( + customer_id=customer_id, extension_type=extension_type, + ) + + @staticmethod + def parse_customer_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a customer_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerExtensionSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CustomerExtensionSettingServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer extension setting service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerExtensionSettingServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerExtensionSettingServiceTransport): + # transport is a CustomerExtensionSettingServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_extension_settings( + self, + request: Union[ + customer_extension_setting_service.MutateCustomerExtensionSettingsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_extension_setting_service.CustomerExtensionSettingOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_extension_setting_service.MutateCustomerExtensionSettingsResponse: + r"""Creates, updates, or removes customer extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerExtensionSettingsRequest, dict]): + The request object. Request message for + [CustomerExtensionSettingService.MutateCustomerExtensionSettings][google.ads.googleads.v12.services.CustomerExtensionSettingService.MutateCustomerExtensionSettings]. + customer_id (str): + Required. The ID of the customer + whose customer extension settings are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerExtensionSettingOperation]): + Required. The list of operations to + perform on individual customer extension + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerExtensionSettingsResponse: + Response message for a customer + extension setting mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_extension_setting_service.MutateCustomerExtensionSettingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_extension_setting_service.MutateCustomerExtensionSettingsRequest, + ): + request = customer_extension_setting_service.MutateCustomerExtensionSettingsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_extension_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerExtensionSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/__init__.py new file mode 100644 index 000000000..2a0bd502a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerExtensionSettingServiceTransport +from .grpc import CustomerExtensionSettingServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerExtensionSettingServiceTransport]] +_transport_registry["grpc"] = CustomerExtensionSettingServiceGrpcTransport + +__all__ = ( + "CustomerExtensionSettingServiceTransport", + "CustomerExtensionSettingServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/base.py new file mode 100644 index 000000000..3cbe645de --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_extension_setting_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerExtensionSettingServiceTransport(abc.ABC): + """Abstract transport class for CustomerExtensionSettingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_extension_settings: gapic_v1.method.wrap_method( + self.mutate_customer_extension_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_extension_settings( + self, + ) -> Callable[ + [ + customer_extension_setting_service.MutateCustomerExtensionSettingsRequest + ], + Union[ + customer_extension_setting_service.MutateCustomerExtensionSettingsResponse, + Awaitable[ + customer_extension_setting_service.MutateCustomerExtensionSettingsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerExtensionSettingServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/grpc.py new file mode 100644 index 000000000..478014608 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_extension_setting_service/transports/grpc.py @@ -0,0 +1,290 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_extension_setting_service, +) +from .base import CustomerExtensionSettingServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerExtensionSettingServiceGrpcTransport( + CustomerExtensionSettingServiceTransport +): + """gRPC backend transport for CustomerExtensionSettingService. + + Service to manage customer extension settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_extension_settings( + self, + ) -> Callable[ + [ + customer_extension_setting_service.MutateCustomerExtensionSettingsRequest + ], + customer_extension_setting_service.MutateCustomerExtensionSettingsResponse, + ]: + r"""Return a callable for the mutate customer extension + settings method over gRPC. + + Creates, updates, or removes customer extension settings. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionSettingError <>`__ + `FieldError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCustomerExtensionSettingsRequest], + ~.MutateCustomerExtensionSettingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_extension_settings" not in self._stubs: + self._stubs[ + "mutate_customer_extension_settings" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerExtensionSettingService/MutateCustomerExtensionSettings", + request_serializer=customer_extension_setting_service.MutateCustomerExtensionSettingsRequest.serialize, + response_deserializer=customer_extension_setting_service.MutateCustomerExtensionSettingsResponse.deserialize, + ) + return self._stubs["mutate_customer_extension_settings"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerExtensionSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_feed_service/__init__.py b/google/ads/googleads/v12/services/services/customer_feed_service/__init__.py new file mode 100644 index 000000000..3586047a2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_feed_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerFeedServiceClient + +__all__ = ("CustomerFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_feed_service/client.py b/google/ads/googleads/v12/services/services/customer_feed_service/client.py new file mode 100644 index 000000000..177ff18f8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_feed_service/client.py @@ -0,0 +1,509 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_feed_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerFeedServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerFeedServiceGrpcTransport + + +class CustomerFeedServiceClientMeta(type): + """Metaclass for the CustomerFeedService 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[CustomerFeedServiceTransport]] + _transport_registry["grpc"] = CustomerFeedServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerFeedServiceTransport]: + """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 CustomerFeedServiceClient(metaclass=CustomerFeedServiceClientMeta): + """Service to manage customer feeds.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerFeedServiceClient: 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: + CustomerFeedServiceClient: 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) -> CustomerFeedServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerFeedServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified customer_feed string.""" + return "customers/{customer_id}/customerFeeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_customer_feed_path(path: str) -> Dict[str, str]: + """Parses a customer_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerFeeds/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerFeedServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer feed 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 (Union[str, CustomerFeedServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerFeedServiceTransport): + # transport is a CustomerFeedServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_feeds( + self, + request: Union[ + customer_feed_service.MutateCustomerFeedsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_feed_service.CustomerFeedOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_feed_service.MutateCustomerFeedsResponse: + r"""Creates, updates, or removes customer feeds. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CustomerFeedError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `FunctionParsingError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerFeedsRequest, dict]): + The request object. Request message for + [CustomerFeedService.MutateCustomerFeeds][google.ads.googleads.v12.services.CustomerFeedService.MutateCustomerFeeds]. + customer_id (str): + Required. The ID of the customer + whose customer feeds are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerFeedOperation]): + Required. The list of operations to + perform on individual customer feeds. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerFeedsResponse: + Response message for a customer feed + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_feed_service.MutateCustomerFeedsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_feed_service.MutateCustomerFeedsRequest + ): + request = customer_feed_service.MutateCustomerFeedsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_feeds + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerFeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_feed_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_feed_service/transports/__init__.py new file mode 100644 index 000000000..9f3711a35 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_feed_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerFeedServiceTransport +from .grpc import CustomerFeedServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerFeedServiceTransport]] +_transport_registry["grpc"] = CustomerFeedServiceGrpcTransport + +__all__ = ( + "CustomerFeedServiceTransport", + "CustomerFeedServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_feed_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_feed_service/transports/base.py new file mode 100644 index 000000000..b5841e418 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_feed_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_feed_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerFeedServiceTransport(abc.ABC): + """Abstract transport class for CustomerFeedService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_feeds: gapic_v1.method.wrap_method( + self.mutate_customer_feeds, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_feeds( + self, + ) -> Callable[ + [customer_feed_service.MutateCustomerFeedsRequest], + Union[ + customer_feed_service.MutateCustomerFeedsResponse, + Awaitable[customer_feed_service.MutateCustomerFeedsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerFeedServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_feed_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_feed_service/transports/grpc.py new file mode 100644 index 000000000..d459ae8d9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_feed_service/transports/grpc.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_feed_service +from .base import CustomerFeedServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerFeedServiceGrpcTransport(CustomerFeedServiceTransport): + """gRPC backend transport for CustomerFeedService. + + Service to manage customer feeds. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_feeds( + self, + ) -> Callable[ + [customer_feed_service.MutateCustomerFeedsRequest], + customer_feed_service.MutateCustomerFeedsResponse, + ]: + r"""Return a callable for the mutate customer feeds method over gRPC. + + Creates, updates, or removes customer feeds. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CustomerFeedError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `FunctionParsingError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCustomerFeedsRequest], + ~.MutateCustomerFeedsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_feeds" not in self._stubs: + self._stubs[ + "mutate_customer_feeds" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerFeedService/MutateCustomerFeeds", + request_serializer=customer_feed_service.MutateCustomerFeedsRequest.serialize, + response_deserializer=customer_feed_service.MutateCustomerFeedsResponse.deserialize, + ) + return self._stubs["mutate_customer_feeds"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerFeedServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_label_service/__init__.py b/google/ads/googleads/v12/services/services/customer_label_service/__init__.py new file mode 100644 index 000000000..36d12fc0a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerLabelServiceClient + +__all__ = ("CustomerLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_label_service/client.py b/google/ads/googleads/v12/services/services/customer_label_service/client.py new file mode 100644 index 000000000..23f409529 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_label_service/client.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerLabelServiceGrpcTransport + + +class CustomerLabelServiceClientMeta(type): + """Metaclass for the CustomerLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerLabelServiceTransport]] + _transport_registry["grpc"] = CustomerLabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerLabelServiceClient(metaclass=CustomerLabelServiceClientMeta): + """Service to manage labels on customers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerLabelServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerLabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerLabelServiceTransport): + # transport is a CustomerLabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_labels( + self, + request: Union[ + customer_label_service.MutateCustomerLabelsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_label_service.CustomerLabelOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_label_service.MutateCustomerLabelsResponse: + r"""Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerLabelsRequest, dict]): + The request object. Request message for + [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v12.services.CustomerLabelService.MutateCustomerLabels]. + customer_id (str): + Required. ID of the customer whose + customer-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerLabelOperation]): + Required. The list of operations to + perform on customer-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerLabelsResponse: + Response message for a customer + labels mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_label_service.MutateCustomerLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_label_service.MutateCustomerLabelsRequest + ): + request = customer_label_service.MutateCustomerLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerLabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_label_service/transports/__init__.py new file mode 100644 index 000000000..6ca9f71d6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerLabelServiceTransport +from .grpc import CustomerLabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerLabelServiceTransport]] +_transport_registry["grpc"] = CustomerLabelServiceGrpcTransport + +__all__ = ( + "CustomerLabelServiceTransport", + "CustomerLabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_label_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_label_service/transports/base.py new file mode 100644 index 000000000..f7a06b908 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_label_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_label_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerLabelServiceTransport(abc.ABC): + """Abstract transport class for CustomerLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_labels: gapic_v1.method.wrap_method( + self.mutate_customer_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_labels( + self, + ) -> Callable[ + [customer_label_service.MutateCustomerLabelsRequest], + Union[ + customer_label_service.MutateCustomerLabelsResponse, + Awaitable[customer_label_service.MutateCustomerLabelsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerLabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_label_service/transports/grpc.py new file mode 100644 index 000000000..a9f7f0c6f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_label_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_label_service +from .base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerLabelServiceGrpcTransport(CustomerLabelServiceTransport): + """gRPC backend transport for CustomerLabelService. + + Service to manage labels on customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_labels( + self, + ) -> Callable[ + [customer_label_service.MutateCustomerLabelsRequest], + customer_label_service.MutateCustomerLabelsResponse, + ]: + r"""Return a callable for the mutate customer labels method over gRPC. + + Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerLabelsRequest], + ~.MutateCustomerLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_labels" not in self._stubs: + self._stubs[ + "mutate_customer_labels" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerLabelService/MutateCustomerLabels", + request_serializer=customer_label_service.MutateCustomerLabelsRequest.serialize, + response_deserializer=customer_label_service.MutateCustomerLabelsResponse.deserialize, + ) + return self._stubs["mutate_customer_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_manager_link_service/__init__.py b/google/ads/googleads/v12/services/services/customer_manager_link_service/__init__.py new file mode 100644 index 000000000..81294402e --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_manager_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerManagerLinkServiceClient + +__all__ = ("CustomerManagerLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_manager_link_service/client.py b/google/ads/googleads/v12/services/services/customer_manager_link_service/client.py new file mode 100644 index 000000000..5351b52b9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_manager_link_service/client.py @@ -0,0 +1,633 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_manager_link_service, +) +from .transports.base import ( + CustomerManagerLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerManagerLinkServiceGrpcTransport + + +class CustomerManagerLinkServiceClientMeta(type): + """Metaclass for the CustomerManagerLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerManagerLinkServiceTransport]] + _transport_registry["grpc"] = CustomerManagerLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerManagerLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerManagerLinkServiceClient( + metaclass=CustomerManagerLinkServiceClientMeta +): + """Service to manage customer-manager links.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerManagerLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerManagerLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_manager_link_path( + customer_id: str, manager_customer_id: str, manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_manager_link string.""" + return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + manager_customer_id=manager_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_manager_link_path(path: str) -> Dict[str, str]: + """Parses a customer_manager_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerManagerLinkServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer manager link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerManagerLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerManagerLinkServiceTransport): + # transport is a CustomerManagerLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_manager_link( + self, + request: Union[ + customer_manager_link_service.MutateCustomerManagerLinkRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_manager_link_service.CustomerManagerLinkOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_manager_link_service.MutateCustomerManagerLinkResponse: + r"""Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerManagerLinkRequest, dict]): + The request object. Request message for + [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v12.services.CustomerManagerLinkService.MutateCustomerManagerLink]. + customer_id (str): + Required. The ID of the customer + whose customer manager links are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerManagerLinkOperation]): + Required. The list of operations to + perform on individual customer manager + links. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerManagerLinkResponse: + Response message for a + CustomerManagerLink mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_manager_link_service.MutateCustomerManagerLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_manager_link_service.MutateCustomerManagerLinkRequest, + ): + request = customer_manager_link_service.MutateCustomerManagerLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def move_manager_link( + self, + request: Union[ + customer_manager_link_service.MoveManagerLinkRequest, dict + ] = None, + *, + customer_id: str = None, + previous_customer_manager_link: str = None, + new_manager: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_manager_link_service.MoveManagerLinkResponse: + r"""Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MoveManagerLinkRequest, dict]): + The request object. Request message for + [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v12.services.CustomerManagerLinkService.MoveManagerLink]. + customer_id (str): + Required. The ID of the client + customer that is being moved. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + previous_customer_manager_link (str): + Required. The resource name of the previous + CustomerManagerLink. The resource name has the form: + ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` + + This corresponds to the ``previous_customer_manager_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + new_manager (str): + Required. The resource name of the new manager customer + that the client wants to move to. Customer resource + names have the format: "customers/{customer_id}" + + This corresponds to the ``new_manager`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MoveManagerLinkResponse: + Response message for a + CustomerManagerLink moveManagerLink. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [customer_id, previous_customer_manager_link, new_manager] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_manager_link_service.MoveManagerLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_manager_link_service.MoveManagerLinkRequest + ): + request = customer_manager_link_service.MoveManagerLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if previous_customer_manager_link is not None: + request.previous_customer_manager_link = ( + previous_customer_manager_link + ) + if new_manager is not None: + request.new_manager = new_manager + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.move_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerManagerLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/__init__.py new file mode 100644 index 000000000..0af42ed7f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerManagerLinkServiceTransport +from .grpc import CustomerManagerLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerManagerLinkServiceTransport]] +_transport_registry["grpc"] = CustomerManagerLinkServiceGrpcTransport + +__all__ = ( + "CustomerManagerLinkServiceTransport", + "CustomerManagerLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/base.py new file mode 100644 index 000000000..7a3b1cf3d --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_manager_link_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerManagerLinkServiceTransport(abc.ABC): + """Abstract transport class for CustomerManagerLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_manager_link: gapic_v1.method.wrap_method( + self.mutate_customer_manager_link, + default_timeout=None, + client_info=client_info, + ), + self.move_manager_link: gapic_v1.method.wrap_method( + self.move_manager_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MutateCustomerManagerLinkRequest], + Union[ + customer_manager_link_service.MutateCustomerManagerLinkResponse, + Awaitable[ + customer_manager_link_service.MutateCustomerManagerLinkResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def move_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MoveManagerLinkRequest], + Union[ + customer_manager_link_service.MoveManagerLinkResponse, + Awaitable[customer_manager_link_service.MoveManagerLinkResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerManagerLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/grpc.py new file mode 100644 index 000000000..c091f169f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_manager_link_service/transports/grpc.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_manager_link_service, +) +from .base import CustomerManagerLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerManagerLinkServiceGrpcTransport( + CustomerManagerLinkServiceTransport +): + """gRPC backend transport for CustomerManagerLinkService. + + Service to manage customer-manager links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MutateCustomerManagerLinkRequest], + customer_manager_link_service.MutateCustomerManagerLinkResponse, + ]: + r"""Return a callable for the mutate customer manager link method over gRPC. + + Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerManagerLinkRequest], + ~.MutateCustomerManagerLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_manager_link" not in self._stubs: + self._stubs[ + "mutate_customer_manager_link" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerManagerLinkService/MutateCustomerManagerLink", + request_serializer=customer_manager_link_service.MutateCustomerManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MutateCustomerManagerLinkResponse.deserialize, + ) + return self._stubs["mutate_customer_manager_link"] + + @property + def move_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MoveManagerLinkRequest], + customer_manager_link_service.MoveManagerLinkResponse, + ]: + r"""Return a callable for the move manager link method over gRPC. + + Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MoveManagerLinkRequest], + ~.MoveManagerLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "move_manager_link" not in self._stubs: + self._stubs["move_manager_link"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerManagerLinkService/MoveManagerLink", + request_serializer=customer_manager_link_service.MoveManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MoveManagerLinkResponse.deserialize, + ) + return self._stubs["move_manager_link"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerManagerLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_negative_criterion_service/__init__.py b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/__init__.py new file mode 100644 index 000000000..49093ba68 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerNegativeCriterionServiceClient + +__all__ = ("CustomerNegativeCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_negative_criterion_service/client.py b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/client.py new file mode 100644 index 000000000..fe24a24cf --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/client.py @@ -0,0 +1,503 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_negative_criterion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerNegativeCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerNegativeCriterionServiceGrpcTransport + + +class CustomerNegativeCriterionServiceClientMeta(type): + """Metaclass for the CustomerNegativeCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerNegativeCriterionServiceTransport]] + _transport_registry["grpc"] = CustomerNegativeCriterionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerNegativeCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerNegativeCriterionServiceClient( + metaclass=CustomerNegativeCriterionServiceClientMeta +): + """Service to manage customer negative criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerNegativeCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerNegativeCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CustomerNegativeCriterionServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer negative criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerNegativeCriterionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerNegativeCriterionServiceTransport): + # transport is a CustomerNegativeCriterionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_negative_criteria( + self, + request: Union[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customer_negative_criterion_service.CustomerNegativeCriterionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse: + r"""Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerNegativeCriteriaRequest, dict]): + The request object. Request message for + [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v12.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. + customer_id (str): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerNegativeCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerNegativeCriteriaResponse: + Response message for customer + negative criterion mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + ): + request = customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_negative_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerNegativeCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/__init__.py new file mode 100644 index 000000000..7856de5f0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerNegativeCriterionServiceTransport +from .grpc import CustomerNegativeCriterionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerNegativeCriterionServiceTransport]] +_transport_registry["grpc"] = CustomerNegativeCriterionServiceGrpcTransport + +__all__ = ( + "CustomerNegativeCriterionServiceTransport", + "CustomerNegativeCriterionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/base.py new file mode 100644 index 000000000..e860cfee6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_negative_criterion_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerNegativeCriterionServiceTransport(abc.ABC): + """Abstract transport class for CustomerNegativeCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_negative_criteria: gapic_v1.method.wrap_method( + self.mutate_customer_negative_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_negative_criteria( + self, + ) -> Callable[ + [ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest + ], + Union[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, + Awaitable[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerNegativeCriterionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/grpc.py new file mode 100644 index 000000000..93cd55ce5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_negative_criterion_service/transports/grpc.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_negative_criterion_service, +) +from .base import CustomerNegativeCriterionServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerNegativeCriterionServiceGrpcTransport( + CustomerNegativeCriterionServiceTransport +): + """gRPC backend transport for CustomerNegativeCriterionService. + + Service to manage customer negative criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_negative_criteria( + self, + ) -> Callable[ + [ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest + ], + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, + ]: + r"""Return a callable for the mutate customer negative + criteria method over gRPC. + + Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerNegativeCriteriaRequest], + ~.MutateCustomerNegativeCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_negative_criteria" not in self._stubs: + self._stubs[ + "mutate_customer_negative_criteria" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerNegativeCriterionService/MutateCustomerNegativeCriteria", + request_serializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest.serialize, + response_deserializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse.deserialize, + ) + return self._stubs["mutate_customer_negative_criteria"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerNegativeCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_service/__init__.py b/google/ads/googleads/v12/services/services/customer_service/__init__.py new file mode 100644 index 000000000..a097717ec --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerServiceClient + +__all__ = ("CustomerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_service/client.py b/google/ads/googleads/v12/services/services/customer_service/client.py new file mode 100644 index 000000000..86fc0865f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_service/client.py @@ -0,0 +1,646 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import customer +from google.ads.googleads.v12.services.types import customer_service +from .transports.base import CustomerServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerServiceGrpcTransport + + +class CustomerServiceClientMeta(type): + """Metaclass for the CustomerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerServiceTransport]] + _transport_registry["grpc"] = CustomerServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerServiceClient(metaclass=CustomerServiceClientMeta): + """Service to manage customers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerServiceTransport): + # transport is a CustomerServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer( + self, + request: Union[customer_service.MutateCustomerRequest, dict] = None, + *, + customer_id: str = None, + operation: customer_service.CustomerOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_service.MutateCustomerResponse: + r"""Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerRequest, dict]): + The request object. Request message for + [CustomerService.MutateCustomer][google.ads.googleads.v12.services.CustomerService.MutateCustomer]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.CustomerOperation): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerResponse: + Response message for customer mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_service.MutateCustomerRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, customer_service.MutateCustomerRequest): + request = customer_service.MutateCustomerRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_customer] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_accessible_customers( + self, + request: Union[ + customer_service.ListAccessibleCustomersRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_service.ListAccessibleCustomersResponse: + r"""Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListAccessibleCustomersRequest, dict]): + The request object. Request message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v12.services.CustomerService.ListAccessibleCustomers]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListAccessibleCustomersResponse: + Response message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v12.services.CustomerService.ListAccessibleCustomers]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a customer_service.ListAccessibleCustomersRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_service.ListAccessibleCustomersRequest + ): + request = customer_service.ListAccessibleCustomersRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_accessible_customers + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def create_customer_client( + self, + request: Union[ + customer_service.CreateCustomerClientRequest, dict + ] = None, + *, + customer_id: str = None, + customer_client: customer.Customer = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_service.CreateCustomerClientResponse: + r"""Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.CreateCustomerClientRequest, dict]): + The request object. Request message for + [CustomerService.CreateCustomerClient][google.ads.googleads.v12.services.CustomerService.CreateCustomerClient]. + customer_id (str): + Required. The ID of the Manager under + whom client customer is being created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + customer_client (google.ads.googleads.v12.resources.types.Customer): + Required. The new client customer to + create. The resource name on this + customer will be ignored. + + This corresponds to the ``customer_client`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.CreateCustomerClientResponse: + Response message for + CreateCustomerClient mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, customer_client]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_service.CreateCustomerClientRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, customer_service.CreateCustomerClientRequest + ): + request = customer_service.CreateCustomerClientRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if customer_client is not None: + request.customer_client = customer_client + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_customer_client + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_service/transports/__init__.py new file mode 100644 index 000000000..544c0f14c --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerServiceTransport +from .grpc import CustomerServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerServiceTransport]] +_transport_registry["grpc"] = CustomerServiceGrpcTransport + +__all__ = ( + "CustomerServiceTransport", + "CustomerServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_service/transports/base.py new file mode 100644 index 000000000..63d878085 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_service/transports/base.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerServiceTransport(abc.ABC): + """Abstract transport class for CustomerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer: gapic_v1.method.wrap_method( + self.mutate_customer, + default_timeout=None, + client_info=client_info, + ), + self.list_accessible_customers: gapic_v1.method.wrap_method( + self.list_accessible_customers, + default_timeout=None, + client_info=client_info, + ), + self.create_customer_client: gapic_v1.method.wrap_method( + self.create_customer_client, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer( + self, + ) -> Callable[ + [customer_service.MutateCustomerRequest], + Union[ + customer_service.MutateCustomerResponse, + Awaitable[customer_service.MutateCustomerResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_accessible_customers( + self, + ) -> Callable[ + [customer_service.ListAccessibleCustomersRequest], + Union[ + customer_service.ListAccessibleCustomersResponse, + Awaitable[customer_service.ListAccessibleCustomersResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_customer_client( + self, + ) -> Callable[ + [customer_service.CreateCustomerClientRequest], + Union[ + customer_service.CreateCustomerClientResponse, + Awaitable[customer_service.CreateCustomerClientResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_service/transports/grpc.py new file mode 100644 index 000000000..fa6ec6f51 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_service/transports/grpc.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_service +from .base import CustomerServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerServiceGrpcTransport(CustomerServiceTransport): + """gRPC backend transport for CustomerService. + + Service to manage customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer( + self, + ) -> Callable[ + [customer_service.MutateCustomerRequest], + customer_service.MutateCustomerResponse, + ]: + r"""Return a callable for the mutate customer method over gRPC. + + Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCustomerRequest], + ~.MutateCustomerResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer" not in self._stubs: + self._stubs["mutate_customer"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerService/MutateCustomer", + request_serializer=customer_service.MutateCustomerRequest.serialize, + response_deserializer=customer_service.MutateCustomerResponse.deserialize, + ) + return self._stubs["mutate_customer"] + + @property + def list_accessible_customers( + self, + ) -> Callable[ + [customer_service.ListAccessibleCustomersRequest], + customer_service.ListAccessibleCustomersResponse, + ]: + r"""Return a callable for the list accessible customers method over gRPC. + + Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListAccessibleCustomersRequest], + ~.ListAccessibleCustomersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_accessible_customers" not in self._stubs: + self._stubs[ + "list_accessible_customers" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerService/ListAccessibleCustomers", + request_serializer=customer_service.ListAccessibleCustomersRequest.serialize, + response_deserializer=customer_service.ListAccessibleCustomersResponse.deserialize, + ) + return self._stubs["list_accessible_customers"] + + @property + def create_customer_client( + self, + ) -> Callable[ + [customer_service.CreateCustomerClientRequest], + customer_service.CreateCustomerClientResponse, + ]: + r"""Return a callable for the create customer client method over gRPC. + + Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Returns: + Callable[[~.CreateCustomerClientRequest], + ~.CreateCustomerClientResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_customer_client" not in self._stubs: + self._stubs[ + "create_customer_client" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerService/CreateCustomerClient", + request_serializer=customer_service.CreateCustomerClientRequest.serialize, + response_deserializer=customer_service.CreateCustomerClientResponse.deserialize, + ) + return self._stubs["create_customer_client"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/__init__.py b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/__init__.py new file mode 100644 index 000000000..b723bd090 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerUserAccessInvitationServiceClient + +__all__ = ("CustomerUserAccessInvitationServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/client.py b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/client.py new file mode 100644 index 000000000..e4b6d3b52 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/client.py @@ -0,0 +1,504 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_user_access_invitation_service, +) +from .transports.base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerUserAccessInvitationServiceGrpcTransport + + +class CustomerUserAccessInvitationServiceClientMeta(type): + """Metaclass for the CustomerUserAccessInvitationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerUserAccessInvitationServiceTransport]] + _transport_registry[ + "grpc" + ] = CustomerUserAccessInvitationServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerUserAccessInvitationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerUserAccessInvitationServiceClient( + metaclass=CustomerUserAccessInvitationServiceClientMeta +): + """This service manages the access invitation extended to users + for a given customer. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerUserAccessInvitationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessInvitationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_user_access_invitation_path( + customer_id: str, invitation_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access_invitation string.""" + return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( + customer_id=customer_id, invitation_id=invitation_id, + ) + + @staticmethod + def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, CustomerUserAccessInvitationServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access invitation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerUserAccessInvitationServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerUserAccessInvitationServiceTransport): + # transport is a CustomerUserAccessInvitationServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_user_access_invitation( + self, + request: Union[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + dict, + ] = None, + *, + customer_id: str = None, + operation: customer_user_access_invitation_service.CustomerUserAccessInvitationOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse: + r"""Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerUserAccessInvitationRequest, dict]): + The request object. Request message for + [CustomerUserAccessInvitation.MutateCustomerUserAccessInvitation][] + customer_id (str): + Required. The ID of the customer + whose access invitation is being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.CustomerUserAccessInvitationOperation): + Required. The operation to perform on + the access invitation + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerUserAccessInvitationResponse: + Response message for access + invitation mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + ): + request = customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_user_access_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerUserAccessInvitationServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/__init__.py new file mode 100644 index 000000000..f8aaf535f --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerUserAccessInvitationServiceTransport +from .grpc import CustomerUserAccessInvitationServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerUserAccessInvitationServiceTransport]] +_transport_registry["grpc"] = CustomerUserAccessInvitationServiceGrpcTransport + +__all__ = ( + "CustomerUserAccessInvitationServiceTransport", + "CustomerUserAccessInvitationServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/base.py new file mode 100644 index 000000000..b17b6160a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_user_access_invitation_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerUserAccessInvitationServiceTransport(abc.ABC): + """Abstract transport class for CustomerUserAccessInvitationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_user_access_invitation: gapic_v1.method.wrap_method( + self.mutate_customer_user_access_invitation, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_user_access_invitation( + self, + ) -> Callable[ + [ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest + ], + Union[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, + Awaitable[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerUserAccessInvitationServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/grpc.py new file mode 100644 index 000000000..7947e6a8b --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_invitation_service/transports/grpc.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + customer_user_access_invitation_service, +) +from .base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class CustomerUserAccessInvitationServiceGrpcTransport( + CustomerUserAccessInvitationServiceTransport +): + """gRPC backend transport for CustomerUserAccessInvitationService. + + This service manages the access invitation extended to users + for a given customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_user_access_invitation( + self, + ) -> Callable[ + [ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest + ], + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, + ]: + r"""Return a callable for the mutate customer user access + invitation method over gRPC. + + Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessInvitationRequest], + ~.MutateCustomerUserAccessInvitationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access_invitation" not in self._stubs: + self._stubs[ + "mutate_customer_user_access_invitation" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerUserAccessInvitationService/MutateCustomerUserAccessInvitation", + request_serializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest.serialize, + response_deserializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse.deserialize, + ) + return self._stubs["mutate_customer_user_access_invitation"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerUserAccessInvitationServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_service/__init__.py b/google/ads/googleads/v12/services/services/customer_user_access_service/__init__.py new file mode 100644 index 000000000..6159ad18a --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomerUserAccessServiceClient + +__all__ = ("CustomerUserAccessServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_service/client.py b/google/ads/googleads/v12/services/services/customer_user_access_service/client.py new file mode 100644 index 000000000..98868b372 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_service/client.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customer_user_access_service +from .transports.base import ( + CustomerUserAccessServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerUserAccessServiceGrpcTransport + + +class CustomerUserAccessServiceClientMeta(type): + """Metaclass for the CustomerUserAccessService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerUserAccessServiceTransport]] + _transport_registry["grpc"] = CustomerUserAccessServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomerUserAccessServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerUserAccessServiceClient( + metaclass=CustomerUserAccessServiceClientMeta +): + """This service manages the permissions of a user on a given + customer. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerUserAccessServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_user_access_path(customer_id: str, user_id: str,) -> str: + """Returns a fully-qualified customer_user_access string.""" + return "customers/{customer_id}/customerUserAccesses/{user_id}".format( + customer_id=customer_id, user_id=user_id, + ) + + @staticmethod + def parse_customer_user_access_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomerUserAccessServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomerUserAccessServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomerUserAccessServiceTransport): + # transport is a CustomerUserAccessServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customer_user_access( + self, + request: Union[ + customer_user_access_service.MutateCustomerUserAccessRequest, dict + ] = None, + *, + customer_id: str = None, + operation: customer_user_access_service.CustomerUserAccessOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customer_user_access_service.MutateCustomerUserAccessResponse: + r"""Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomerUserAccessRequest, dict]): + The request object. Mutate Request for + [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v12.services.CustomerUserAccessService.MutateCustomerUserAccess]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.CustomerUserAccessOperation): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomerUserAccessResponse: + Response message for customer user + access mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customer_user_access_service.MutateCustomerUserAccessRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customer_user_access_service.MutateCustomerUserAccessRequest, + ): + request = customer_user_access_service.MutateCustomerUserAccessRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_user_access + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomerUserAccessServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/__init__.py new file mode 100644 index 000000000..d7ed028e1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomerUserAccessServiceTransport +from .grpc import CustomerUserAccessServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomerUserAccessServiceTransport]] +_transport_registry["grpc"] = CustomerUserAccessServiceGrpcTransport + +__all__ = ( + "CustomerUserAccessServiceTransport", + "CustomerUserAccessServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_service/transports/base.py b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/base.py new file mode 100644 index 000000000..cda3ba933 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customer_user_access_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomerUserAccessServiceTransport(abc.ABC): + """Abstract transport class for CustomerUserAccessService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_user_access: gapic_v1.method.wrap_method( + self.mutate_customer_user_access, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_user_access( + self, + ) -> Callable[ + [customer_user_access_service.MutateCustomerUserAccessRequest], + Union[ + customer_user_access_service.MutateCustomerUserAccessResponse, + Awaitable[ + customer_user_access_service.MutateCustomerUserAccessResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomerUserAccessServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customer_user_access_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/grpc.py new file mode 100644 index 000000000..1bb345bd1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customer_user_access_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customer_user_access_service +from .base import CustomerUserAccessServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomerUserAccessServiceGrpcTransport( + CustomerUserAccessServiceTransport +): + """gRPC backend transport for CustomerUserAccessService. + + This service manages the permissions of a user on a given + customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customer_user_access( + self, + ) -> Callable[ + [customer_user_access_service.MutateCustomerUserAccessRequest], + customer_user_access_service.MutateCustomerUserAccessResponse, + ]: + r"""Return a callable for the mutate customer user access method over gRPC. + + Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessRequest], + ~.MutateCustomerUserAccessResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access" not in self._stubs: + self._stubs[ + "mutate_customer_user_access" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomerUserAccessService/MutateCustomerUserAccess", + request_serializer=customer_user_access_service.MutateCustomerUserAccessRequest.serialize, + response_deserializer=customer_user_access_service.MutateCustomerUserAccessResponse.deserialize, + ) + return self._stubs["mutate_customer_user_access"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomerUserAccessServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/customizer_attribute_service/__init__.py b/google/ads/googleads/v12/services/services/customizer_attribute_service/__init__.py new file mode 100644 index 000000000..5db157a51 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customizer_attribute_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CustomizerAttributeServiceClient + +__all__ = ("CustomizerAttributeServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customizer_attribute_service/client.py b/google/ads/googleads/v12/services/services/customizer_attribute_service/client.py new file mode 100644 index 000000000..84668a7de --- /dev/null +++ b/google/ads/googleads/v12/services/services/customizer_attribute_service/client.py @@ -0,0 +1,496 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import customizer_attribute_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomizerAttributeServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomizerAttributeServiceGrpcTransport + + +class CustomizerAttributeServiceClientMeta(type): + """Metaclass for the CustomizerAttributeService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomizerAttributeServiceTransport]] + _transport_registry["grpc"] = CustomizerAttributeServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[CustomizerAttributeServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomizerAttributeServiceClient( + metaclass=CustomizerAttributeServiceClientMeta +): + """Service to manage customizer attribute""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomizerAttributeServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomizerAttributeServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CustomizerAttributeServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customizer attribute service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, CustomizerAttributeServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, CustomizerAttributeServiceTransport): + # transport is a CustomizerAttributeServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_customizer_attributes( + self, + request: Union[ + customizer_attribute_service.MutateCustomizerAttributesRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + customizer_attribute_service.CustomizerAttributeOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customizer_attribute_service.MutateCustomizerAttributesResponse: + r"""Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateCustomizerAttributesRequest, dict]): + The request object. Request message for + [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v12.services.CustomizerAttributeService.MutateCustomizerAttributes]. + customer_id (str): + Required. The ID of the customer + whose customizer attributes are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.CustomizerAttributeOperation]): + Required. The list of operations to + perform on individual customizer + attributes. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateCustomizerAttributesResponse: + Response message for an customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a customizer_attribute_service.MutateCustomizerAttributesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + customizer_attribute_service.MutateCustomizerAttributesRequest, + ): + request = customizer_attribute_service.MutateCustomizerAttributesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customizer_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("CustomizerAttributeServiceClient",) diff --git a/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/__init__.py b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/__init__.py new file mode 100644 index 000000000..938589ae1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 CustomizerAttributeServiceTransport +from .grpc import CustomizerAttributeServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CustomizerAttributeServiceTransport]] +_transport_registry["grpc"] = CustomizerAttributeServiceGrpcTransport + +__all__ = ( + "CustomizerAttributeServiceTransport", + "CustomizerAttributeServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/base.py b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/base.py new file mode 100644 index 000000000..9c9fc73cf --- /dev/null +++ b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import customizer_attribute_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class CustomizerAttributeServiceTransport(abc.ABC): + """Abstract transport class for CustomizerAttributeService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customizer_attributes: gapic_v1.method.wrap_method( + self.mutate_customizer_attributes, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customizer_attributes( + self, + ) -> Callable[ + [customizer_attribute_service.MutateCustomizerAttributesRequest], + Union[ + customizer_attribute_service.MutateCustomizerAttributesResponse, + Awaitable[ + customizer_attribute_service.MutateCustomizerAttributesResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("CustomizerAttributeServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/grpc.py b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/grpc.py new file mode 100644 index 000000000..6ff086d30 --- /dev/null +++ b/google/ads/googleads/v12/services/services/customizer_attribute_service/transports/grpc.py @@ -0,0 +1,273 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import customizer_attribute_service +from .base import CustomizerAttributeServiceTransport, DEFAULT_CLIENT_INFO + + +class CustomizerAttributeServiceGrpcTransport( + CustomizerAttributeServiceTransport +): + """gRPC backend transport for CustomizerAttributeService. + + Service to manage customizer attribute + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_customizer_attributes( + self, + ) -> Callable[ + [customizer_attribute_service.MutateCustomizerAttributesRequest], + customizer_attribute_service.MutateCustomizerAttributesResponse, + ]: + r"""Return a callable for the mutate customizer attributes method over gRPC. + + Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomizerAttributesRequest], + ~.MutateCustomizerAttributesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customizer_attributes" not in self._stubs: + self._stubs[ + "mutate_customizer_attributes" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.CustomizerAttributeService/MutateCustomizerAttributes", + request_serializer=customizer_attribute_service.MutateCustomizerAttributesRequest.serialize, + response_deserializer=customizer_attribute_service.MutateCustomizerAttributesResponse.deserialize, + ) + return self._stubs["mutate_customizer_attributes"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("CustomizerAttributeServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/experiment_arm_service/__init__.py b/google/ads/googleads/v12/services/services/experiment_arm_service/__init__.py new file mode 100644 index 000000000..7d07dade9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_arm_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ExperimentArmServiceClient + +__all__ = ("ExperimentArmServiceClient",) diff --git a/google/ads/googleads/v12/services/services/experiment_arm_service/client.py b/google/ads/googleads/v12/services/services/experiment_arm_service/client.py new file mode 100644 index 000000000..128b7e90f --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_arm_service/client.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import experiment_arm_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ExperimentArmServiceGrpcTransport + + +class ExperimentArmServiceClientMeta(type): + """Metaclass for the ExperimentArmService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ExperimentArmServiceTransport]] + _transport_registry["grpc"] = ExperimentArmServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ExperimentArmServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ExperimentArmServiceClient(metaclass=ExperimentArmServiceClientMeta): + """Service to manage experiment arms.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ExperimentArmServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentArmServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(customer_id: str, trial_id: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, trial_id: str, trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ExperimentArmServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment arm service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ExperimentArmServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ExperimentArmServiceTransport): + # transport is a ExperimentArmServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_experiment_arms( + self, + request: Union[ + experiment_arm_service.MutateExperimentArmsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + experiment_arm_service.ExperimentArmOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> experiment_arm_service.MutateExperimentArmsResponse: + r"""Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateExperimentArmsRequest, dict]): + The request object. Request message for + [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v12.services.ExperimentArmService.MutateExperimentArms]. + customer_id (str): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ExperimentArmOperation]): + Required. The list of operations to + perform on individual experiment arm. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateExperimentArmsResponse: + Response message for experiment arm + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_arm_service.MutateExperimentArmsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, experiment_arm_service.MutateExperimentArmsRequest + ): + request = experiment_arm_service.MutateExperimentArmsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_experiment_arms + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ExperimentArmServiceClient",) diff --git a/google/ads/googleads/v12/services/services/experiment_arm_service/transports/__init__.py b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/__init__.py new file mode 100644 index 000000000..7bc19fc01 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ExperimentArmServiceTransport +from .grpc import ExperimentArmServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ExperimentArmServiceTransport]] +_transport_registry["grpc"] = ExperimentArmServiceGrpcTransport + +__all__ = ( + "ExperimentArmServiceTransport", + "ExperimentArmServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/experiment_arm_service/transports/base.py b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/base.py new file mode 100644 index 000000000..3bd1bc568 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import experiment_arm_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ExperimentArmServiceTransport(abc.ABC): + """Abstract transport class for ExperimentArmService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_experiment_arms: gapic_v1.method.wrap_method( + self.mutate_experiment_arms, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_experiment_arms( + self, + ) -> Callable[ + [experiment_arm_service.MutateExperimentArmsRequest], + Union[ + experiment_arm_service.MutateExperimentArmsResponse, + Awaitable[experiment_arm_service.MutateExperimentArmsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ExperimentArmServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/experiment_arm_service/transports/grpc.py b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/grpc.py new file mode 100644 index 000000000..df34b30ee --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_arm_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import experiment_arm_service +from .base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO + + +class ExperimentArmServiceGrpcTransport(ExperimentArmServiceTransport): + """gRPC backend transport for ExperimentArmService. + + Service to manage experiment arms. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_experiment_arms( + self, + ) -> Callable[ + [experiment_arm_service.MutateExperimentArmsRequest], + experiment_arm_service.MutateExperimentArmsResponse, + ]: + r"""Return a callable for the mutate experiment arms method over gRPC. + + Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentArmsRequest], + ~.MutateExperimentArmsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiment_arms" not in self._stubs: + self._stubs[ + "mutate_experiment_arms" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentArmService/MutateExperimentArms", + request_serializer=experiment_arm_service.MutateExperimentArmsRequest.serialize, + response_deserializer=experiment_arm_service.MutateExperimentArmsResponse.deserialize, + ) + return self._stubs["mutate_experiment_arms"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ExperimentArmServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/experiment_service/__init__.py b/google/ads/googleads/v12/services/services/experiment_service/__init__.py new file mode 100644 index 000000000..0a826a3bc --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ExperimentServiceClient + +__all__ = ("ExperimentServiceClient",) diff --git a/google/ads/googleads/v12/services/services/experiment_service/client.py b/google/ads/googleads/v12/services/services/experiment_service/client.py new file mode 100644 index 000000000..5ebd182c4 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/client.py @@ -0,0 +1,1005 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.services.experiment_service import pagers +from google.ads.googleads.v12.services.types import experiment_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ExperimentServiceGrpcTransport + + +class ExperimentServiceClientMeta(type): + """Metaclass for the ExperimentService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ExperimentServiceTransport]] + _transport_registry["grpc"] = ExperimentServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ExperimentServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ExperimentServiceClient(metaclass=ExperimentServiceClientMeta): + """Service to manage experiments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ExperimentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path(customer_id: str, campaign_budget_id: str,) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(customer_id: str, trial_id: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ExperimentServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ExperimentServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ExperimentServiceTransport): + # transport is a ExperimentServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_experiments( + self, + request: Union[ + experiment_service.MutateExperimentsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[experiment_service.ExperimentOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> experiment_service.MutateExperimentsResponse: + r"""Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateExperimentsRequest, dict]): + The request object. Request message for + [ExperimentService.MutateExperiments][google.ads.googleads.v12.services.ExperimentService.MutateExperiments]. + customer_id (str): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ExperimentOperation]): + Required. The list of operations to + perform on individual experiments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateExperimentsResponse: + Response message for experiment + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.MutateExperimentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, experiment_service.MutateExperimentsRequest): + request = experiment_service.MutateExperimentsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_experiments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def end_experiment( + self, + request: Union[experiment_service.EndExperimentRequest, dict] = None, + *, + experiment: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.EndExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.EndExperiment][google.ads.googleads.v12.services.ExperimentService.EndExperiment]. + experiment (str): + Required. The resource name of the + campaign experiment to end. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([experiment]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.EndExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, experiment_service.EndExperimentRequest): + request = experiment_service.EndExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.end_experiment] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Send the request. + rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + def list_experiment_async_errors( + self, + request: Union[ + experiment_service.ListExperimentAsyncErrorsRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListExperimentAsyncErrorsPager: + r"""Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListExperimentAsyncErrorsRequest, dict]): + The request object. Request message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v12.services.ExperimentService.ListExperimentAsyncErrors]. + resource_name (str): + Required. The name of the experiment + from which to retrieve the async errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.experiment_service.pagers.ListExperimentAsyncErrorsPager: + Response message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v12.services.ExperimentService.ListExperimentAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.ListExperimentAsyncErrorsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, experiment_service.ListExperimentAsyncErrorsRequest + ): + request = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_experiment_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListExperimentAsyncErrorsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def graduate_experiment( + self, + request: Union[ + experiment_service.GraduateExperimentRequest, dict + ] = None, + *, + experiment: str = None, + campaign_budget_mappings: Sequence[ + experiment_service.CampaignBudgetMapping + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GraduateExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.GraduateExperiment][google.ads.googleads.v12.services.ExperimentService.GraduateExperiment]. + experiment (str): + Required. The experiment to be + graduated. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_budget_mappings (Sequence[google.ads.googleads.v12.services.types.CampaignBudgetMapping]): + Required. List of campaign budget + mappings for graduation. Each campaign + that appears here will graduate, and + will be assigned a new budget that is + paired with it in the mapping. The + maximum size is one. + + This corresponds to the ``campaign_budget_mappings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([experiment, campaign_budget_mappings]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.GraduateExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, experiment_service.GraduateExperimentRequest + ): + request = experiment_service.GraduateExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + if campaign_budget_mappings is not None: + request.campaign_budget_mappings = campaign_budget_mappings + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.graduate_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Send the request. + rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + def schedule_experiment( + self, + request: Union[ + experiment_service.ScheduleExperimentRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ScheduleExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.ScheduleExperiment][google.ads.googleads.v12.services.ExperimentService.ScheduleExperiment]. + resource_name (str): + Required. The scheduled experiment. + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.ScheduleExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, experiment_service.ScheduleExperimentRequest + ): + request = experiment_service.ScheduleExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.schedule_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.ScheduleExperimentMetadata, + ) + + # Done; return the response. + return response + + def promote_experiment( + self, + request: Union[ + experiment_service.PromoteExperimentRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.PromoteExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.PromoteExperiment][google.ads.googleads.v12.services.ExperimentService.PromoteExperiment]. + resource_name (str): + Required. The resource name of the + experiment to promote. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a experiment_service.PromoteExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, experiment_service.PromoteExperimentRequest): + request = experiment_service.PromoteExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.promote_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.PromoteExperimentMetadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ExperimentServiceClient",) diff --git a/google/ads/googleads/v12/services/services/experiment_service/pagers.py b/google/ads/googleads/v12/services/services/experiment_service/pagers.py new file mode 100644 index 000000000..4f7550063 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/pagers.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.services.types import experiment_service +from google.rpc import status_pb2 # type: ignore + + +class ListExperimentAsyncErrorsPager: + """A pager for iterating through ``list_experiment_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.ListExperimentAsyncErrorsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListExperimentAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.ListExperimentAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., experiment_service.ListExperimentAsyncErrorsResponse + ], + request: experiment_service.ListExperimentAsyncErrorsRequest, + response: experiment_service.ListExperimentAsyncErrorsResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.ListExperimentAsyncErrorsRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.ListExperimentAsyncErrorsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterable[experiment_service.ListExperimentAsyncErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__(self) -> Iterator[status_pb2.Status]: + for page in self.pages: + yield from page.errors + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/experiment_service/transports/__init__.py b/google/ads/googleads/v12/services/services/experiment_service/transports/__init__.py new file mode 100644 index 000000000..c81291701 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ExperimentServiceTransport +from .grpc import ExperimentServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ExperimentServiceTransport]] +_transport_registry["grpc"] = ExperimentServiceGrpcTransport + +__all__ = ( + "ExperimentServiceTransport", + "ExperimentServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/experiment_service/transports/base.py b/google/ads/googleads/v12/services/services/experiment_service/transports/base.py new file mode 100644 index 000000000..53c49f4f5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/transports/base.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import experiment_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ExperimentServiceTransport(abc.ABC): + """Abstract transport class for ExperimentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_experiments: gapic_v1.method.wrap_method( + self.mutate_experiments, + default_timeout=None, + client_info=client_info, + ), + self.end_experiment: gapic_v1.method.wrap_method( + self.end_experiment, + default_timeout=None, + client_info=client_info, + ), + self.list_experiment_async_errors: gapic_v1.method.wrap_method( + self.list_experiment_async_errors, + default_timeout=None, + client_info=client_info, + ), + self.graduate_experiment: gapic_v1.method.wrap_method( + self.graduate_experiment, + default_timeout=None, + client_info=client_info, + ), + self.schedule_experiment: gapic_v1.method.wrap_method( + self.schedule_experiment, + default_timeout=None, + client_info=client_info, + ), + self.promote_experiment: gapic_v1.method.wrap_method( + self.promote_experiment, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_experiments( + self, + ) -> Callable[ + [experiment_service.MutateExperimentsRequest], + Union[ + experiment_service.MutateExperimentsResponse, + Awaitable[experiment_service.MutateExperimentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def end_experiment( + self, + ) -> Callable[ + [experiment_service.EndExperimentRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def list_experiment_async_errors( + self, + ) -> Callable[ + [experiment_service.ListExperimentAsyncErrorsRequest], + Union[ + experiment_service.ListExperimentAsyncErrorsResponse, + Awaitable[experiment_service.ListExperimentAsyncErrorsResponse], + ], + ]: + raise NotImplementedError() + + @property + def graduate_experiment( + self, + ) -> Callable[ + [experiment_service.GraduateExperimentRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def schedule_experiment( + self, + ) -> Callable[ + [experiment_service.ScheduleExperimentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def promote_experiment( + self, + ) -> Callable[ + [experiment_service.PromoteExperimentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + +__all__ = ("ExperimentServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/experiment_service/transports/grpc.py b/google/ads/googleads/v12/services/services/experiment_service/transports/grpc.py new file mode 100644 index 000000000..be832f478 --- /dev/null +++ b/google/ads/googleads/v12/services/services/experiment_service/transports/grpc.py @@ -0,0 +1,480 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import experiment_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO + + +class ExperimentServiceGrpcTransport(ExperimentServiceTransport): + """gRPC backend transport for ExperimentService. + + Service to manage experiments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: 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 channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_experiments( + self, + ) -> Callable[ + [experiment_service.MutateExperimentsRequest], + experiment_service.MutateExperimentsResponse, + ]: + r"""Return a callable for the mutate experiments method over gRPC. + + Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentsRequest], + ~.MutateExperimentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiments" not in self._stubs: + self._stubs["mutate_experiments"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/MutateExperiments", + request_serializer=experiment_service.MutateExperimentsRequest.serialize, + response_deserializer=experiment_service.MutateExperimentsResponse.deserialize, + ) + return self._stubs["mutate_experiments"] + + @property + def end_experiment( + self, + ) -> Callable[[experiment_service.EndExperimentRequest], empty_pb2.Empty]: + r"""Return a callable for the end experiment method over gRPC. + + Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.EndExperimentRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "end_experiment" not in self._stubs: + self._stubs["end_experiment"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/EndExperiment", + request_serializer=experiment_service.EndExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["end_experiment"] + + @property + def list_experiment_async_errors( + self, + ) -> Callable[ + [experiment_service.ListExperimentAsyncErrorsRequest], + experiment_service.ListExperimentAsyncErrorsResponse, + ]: + r"""Return a callable for the list experiment async errors method over gRPC. + + Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListExperimentAsyncErrorsRequest], + ~.ListExperimentAsyncErrorsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_experiment_async_errors" not in self._stubs: + self._stubs[ + "list_experiment_async_errors" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/ListExperimentAsyncErrors", + request_serializer=experiment_service.ListExperimentAsyncErrorsRequest.serialize, + response_deserializer=experiment_service.ListExperimentAsyncErrorsResponse.deserialize, + ) + return self._stubs["list_experiment_async_errors"] + + @property + def graduate_experiment( + self, + ) -> Callable[ + [experiment_service.GraduateExperimentRequest], empty_pb2.Empty + ]: + r"""Return a callable for the graduate experiment method over gRPC. + + Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GraduateExperimentRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "graduate_experiment" not in self._stubs: + self._stubs["graduate_experiment"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/GraduateExperiment", + request_serializer=experiment_service.GraduateExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["graduate_experiment"] + + @property + def schedule_experiment( + self, + ) -> Callable[ + [experiment_service.ScheduleExperimentRequest], operations_pb2.Operation + ]: + r"""Return a callable for the schedule experiment method over gRPC. + + Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ScheduleExperimentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "schedule_experiment" not in self._stubs: + self._stubs["schedule_experiment"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/ScheduleExperiment", + request_serializer=experiment_service.ScheduleExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["schedule_experiment"] + + @property + def promote_experiment( + self, + ) -> Callable[ + [experiment_service.PromoteExperimentRequest], operations_pb2.Operation + ]: + r"""Return a callable for the promote experiment method over gRPC. + + Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteExperimentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_experiment" not in self._stubs: + self._stubs["promote_experiment"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExperimentService/PromoteExperiment", + request_serializer=experiment_service.PromoteExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["promote_experiment"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ExperimentServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/extension_feed_item_service/__init__.py b/google/ads/googleads/v12/services/services/extension_feed_item_service/__init__.py new file mode 100644 index 000000000..251c00ca9 --- /dev/null +++ b/google/ads/googleads/v12/services/services/extension_feed_item_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ExtensionFeedItemServiceClient + +__all__ = ("ExtensionFeedItemServiceClient",) diff --git a/google/ads/googleads/v12/services/services/extension_feed_item_service/client.py b/google/ads/googleads/v12/services/services/extension_feed_item_service/client.py new file mode 100644 index 000000000..b39144b5e --- /dev/null +++ b/google/ads/googleads/v12/services/services/extension_feed_item_service/client.py @@ -0,0 +1,563 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import extension_feed_item_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ExtensionFeedItemServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ExtensionFeedItemServiceGrpcTransport + + +class ExtensionFeedItemServiceClientMeta(type): + """Metaclass for the ExtensionFeedItemService 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[ExtensionFeedItemServiceTransport]] + _transport_registry["grpc"] = ExtensionFeedItemServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ExtensionFeedItemServiceTransport]: + """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 ExtensionFeedItemServiceClient( + metaclass=ExtensionFeedItemServiceClientMeta +): + """Service to manage extension feed items.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExtensionFeedItemServiceClient: 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: + ExtensionFeedItemServiceClient: 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) -> ExtensionFeedItemServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExtensionFeedItemServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ExtensionFeedItemServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the extension feed item 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 (Union[str, ExtensionFeedItemServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ExtensionFeedItemServiceTransport): + # transport is a ExtensionFeedItemServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_extension_feed_items( + self, + request: Union[ + extension_feed_item_service.MutateExtensionFeedItemsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + extension_feed_item_service.ExtensionFeedItemOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> extension_feed_item_service.MutateExtensionFeedItemsResponse: + r"""Creates, updates, or removes extension feed items. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CountryCodeError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `ImageError <>`__ `InternalError <>`__ `LanguageCodeError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateExtensionFeedItemsRequest, dict]): + The request object. Request message for + [ExtensionFeedItemService.MutateExtensionFeedItems][google.ads.googleads.v12.services.ExtensionFeedItemService.MutateExtensionFeedItems]. + customer_id (str): + Required. The ID of the customer + whose extension feed items are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ExtensionFeedItemOperation]): + Required. The list of operations to + perform on individual extension feed + items. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateExtensionFeedItemsResponse: + Response message for an extension + feed item mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a extension_feed_item_service.MutateExtensionFeedItemsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, extension_feed_item_service.MutateExtensionFeedItemsRequest + ): + request = extension_feed_item_service.MutateExtensionFeedItemsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_extension_feed_items + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ExtensionFeedItemServiceClient",) diff --git a/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/__init__.py b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/__init__.py new file mode 100644 index 000000000..4bc74e637 --- /dev/null +++ b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ExtensionFeedItemServiceTransport +from .grpc import ExtensionFeedItemServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ExtensionFeedItemServiceTransport]] +_transport_registry["grpc"] = ExtensionFeedItemServiceGrpcTransport + +__all__ = ( + "ExtensionFeedItemServiceTransport", + "ExtensionFeedItemServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/base.py b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/base.py new file mode 100644 index 000000000..bf8b99a1d --- /dev/null +++ b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import extension_feed_item_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ExtensionFeedItemServiceTransport(abc.ABC): + """Abstract transport class for ExtensionFeedItemService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_extension_feed_items: gapic_v1.method.wrap_method( + self.mutate_extension_feed_items, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_extension_feed_items( + self, + ) -> Callable[ + [extension_feed_item_service.MutateExtensionFeedItemsRequest], + Union[ + extension_feed_item_service.MutateExtensionFeedItemsResponse, + Awaitable[ + extension_feed_item_service.MutateExtensionFeedItemsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ExtensionFeedItemServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/grpc.py b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/grpc.py new file mode 100644 index 000000000..2b8ba0c34 --- /dev/null +++ b/google/ads/googleads/v12/services/services/extension_feed_item_service/transports/grpc.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import extension_feed_item_service +from .base import ExtensionFeedItemServiceTransport, DEFAULT_CLIENT_INFO + + +class ExtensionFeedItemServiceGrpcTransport(ExtensionFeedItemServiceTransport): + """gRPC backend transport for ExtensionFeedItemService. + + Service to manage extension feed items. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_extension_feed_items( + self, + ) -> Callable[ + [extension_feed_item_service.MutateExtensionFeedItemsRequest], + extension_feed_item_service.MutateExtensionFeedItemsResponse, + ]: + r"""Return a callable for the mutate extension feed items method over gRPC. + + Creates, updates, or removes extension feed items. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CountryCodeError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `ImageError <>`__ `InternalError <>`__ `LanguageCodeError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateExtensionFeedItemsRequest], + ~.MutateExtensionFeedItemsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_extension_feed_items" not in self._stubs: + self._stubs[ + "mutate_extension_feed_items" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ExtensionFeedItemService/MutateExtensionFeedItems", + request_serializer=extension_feed_item_service.MutateExtensionFeedItemsRequest.serialize, + response_deserializer=extension_feed_item_service.MutateExtensionFeedItemsResponse.deserialize, + ) + return self._stubs["mutate_extension_feed_items"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ExtensionFeedItemServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_service/__init__.py b/google/ads/googleads/v12/services/services/feed_item_service/__init__.py new file mode 100644 index 000000000..1b6d39f54 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedItemServiceClient + +__all__ = ("FeedItemServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_service/client.py b/google/ads/googleads/v12/services/services/feed_item_service/client.py new file mode 100644 index 000000000..9e54b854b --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_service/client.py @@ -0,0 +1,506 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import FeedItemServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import FeedItemServiceGrpcTransport + + +class FeedItemServiceClientMeta(type): + """Metaclass for the FeedItemService 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[FeedItemServiceTransport]] + _transport_registry["grpc"] = FeedItemServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedItemServiceTransport]: + """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 FeedItemServiceClient(metaclass=FeedItemServiceClientMeta): + """Service to manage feed items.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedItemServiceClient: 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: + FeedItemServiceClient: 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) -> FeedItemServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedItemServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_path( + customer_id: str, feed_id: str, feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item string.""" + return "customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}".format( + customer_id=customer_id, feed_id=feed_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_path(path: str) -> Dict[str, str]: + """Parses a feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItems/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedItemServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed item 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 (Union[str, FeedItemServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedItemServiceTransport): + # transport is a FeedItemServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feed_items( + self, + request: Union[feed_item_service.MutateFeedItemsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[feed_item_service.FeedItemOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_item_service.MutateFeedItemsResponse: + r"""Creates, updates, or removes feed items. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FeedItemError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedItemsRequest, dict]): + The request object. Request message for + [FeedItemService.MutateFeedItems][google.ads.googleads.v12.services.FeedItemService.MutateFeedItems]. + customer_id (str): + Required. The ID of the customer + whose feed items are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemOperation]): + Required. The list of operations to + perform on individual feed items. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedItemsResponse: + Response message for an feed item + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_item_service.MutateFeedItemsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, feed_item_service.MutateFeedItemsRequest): + request = feed_item_service.MutateFeedItemsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_feed_items + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedItemServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_item_service/transports/__init__.py new file mode 100644 index 000000000..e4bdcfa9d --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedItemServiceTransport +from .grpc import FeedItemServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedItemServiceTransport]] +_transport_registry["grpc"] = FeedItemServiceGrpcTransport + +__all__ = ( + "FeedItemServiceTransport", + "FeedItemServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_item_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_item_service/transports/base.py new file mode 100644 index 000000000..0b6c7242b --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedItemServiceTransport(abc.ABC): + """Abstract transport class for FeedItemService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feed_items: gapic_v1.method.wrap_method( + self.mutate_feed_items, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feed_items( + self, + ) -> Callable[ + [feed_item_service.MutateFeedItemsRequest], + Union[ + feed_item_service.MutateFeedItemsResponse, + Awaitable[feed_item_service.MutateFeedItemsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedItemServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_item_service/transports/grpc.py new file mode 100644 index 000000000..5611e92c5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_service +from .base import FeedItemServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedItemServiceGrpcTransport(FeedItemServiceTransport): + """gRPC backend transport for FeedItemService. + + Service to manage feed items. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feed_items( + self, + ) -> Callable[ + [feed_item_service.MutateFeedItemsRequest], + feed_item_service.MutateFeedItemsResponse, + ]: + r"""Return a callable for the mutate feed items method over gRPC. + + Creates, updates, or removes feed items. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FeedItemError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateFeedItemsRequest], + ~.MutateFeedItemsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feed_items" not in self._stubs: + self._stubs["mutate_feed_items"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedItemService/MutateFeedItems", + request_serializer=feed_item_service.MutateFeedItemsRequest.serialize, + response_deserializer=feed_item_service.MutateFeedItemsResponse.deserialize, + ) + return self._stubs["mutate_feed_items"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedItemServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_link_service/__init__.py b/google/ads/googleads/v12/services/services/feed_item_set_link_service/__init__.py new file mode 100644 index 000000000..980268df6 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedItemSetLinkServiceClient + +__all__ = ("FeedItemSetLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_link_service/client.py b/google/ads/googleads/v12/services/services/feed_item_set_link_service/client.py new file mode 100644 index 000000000..edf3d5353 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_link_service/client.py @@ -0,0 +1,539 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_link_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + FeedItemSetLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import FeedItemSetLinkServiceGrpcTransport + + +class FeedItemSetLinkServiceClientMeta(type): + """Metaclass for the FeedItemSetLinkService 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[FeedItemSetLinkServiceTransport]] + _transport_registry["grpc"] = FeedItemSetLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedItemSetLinkServiceTransport]: + """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 FeedItemSetLinkServiceClient(metaclass=FeedItemSetLinkServiceClientMeta): + """Service to manage feed item set links.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedItemSetLinkServiceClient: 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: + FeedItemSetLinkServiceClient: 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) -> FeedItemSetLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedItemSetLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def feed_item_path( + customer_id: str, feed_id: str, feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item string.""" + return "customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}".format( + customer_id=customer_id, feed_id=feed_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_path(path: str) -> Dict[str, str]: + """Parses a feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItems/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_path( + customer_id: str, feed_id: str, feed_item_set_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set string.""" + return "customers/{customer_id}/feedItemSets/{feed_id}~{feed_item_set_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + ) + + @staticmethod + def parse_feed_item_set_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_link_path( + customer_id: str, + feed_id: str, + feed_item_set_id: str, + feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set_link string.""" + return "customers/{customer_id}/feedItemSetLinks/{feed_id}~{feed_item_set_id}~{feed_item_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_set_link_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSetLinks/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedItemSetLinkServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed item set link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, FeedItemSetLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedItemSetLinkServiceTransport): + # transport is a FeedItemSetLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feed_item_set_links( + self, + request: Union[ + feed_item_set_link_service.MutateFeedItemSetLinksRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + feed_item_set_link_service.FeedItemSetLinkOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_item_set_link_service.MutateFeedItemSetLinksResponse: + r"""Creates, updates, or removes feed item set links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedItemSetLinksRequest, dict]): + The request object. Request message for + [FeedItemSetLinkService.MutateFeedItemSetLinks][google.ads.googleads.v12.services.FeedItemSetLinkService.MutateFeedItemSetLinks]. + customer_id (str): + Required. The ID of the customer + whose feed item set links are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemSetLinkOperation]): + Required. The list of operations to + perform on individual feed item set + links. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedItemSetLinksResponse: + Response message for a feed item set + link mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_item_set_link_service.MutateFeedItemSetLinksRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, feed_item_set_link_service.MutateFeedItemSetLinksRequest + ): + request = feed_item_set_link_service.MutateFeedItemSetLinksRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_feed_item_set_links + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedItemSetLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/__init__.py new file mode 100644 index 000000000..6ae0d29ef --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedItemSetLinkServiceTransport +from .grpc import FeedItemSetLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedItemSetLinkServiceTransport]] +_transport_registry["grpc"] = FeedItemSetLinkServiceGrpcTransport + +__all__ = ( + "FeedItemSetLinkServiceTransport", + "FeedItemSetLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/base.py new file mode 100644 index 000000000..0ecc65bab --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_link_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedItemSetLinkServiceTransport(abc.ABC): + """Abstract transport class for FeedItemSetLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feed_item_set_links: gapic_v1.method.wrap_method( + self.mutate_feed_item_set_links, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feed_item_set_links( + self, + ) -> Callable[ + [feed_item_set_link_service.MutateFeedItemSetLinksRequest], + Union[ + feed_item_set_link_service.MutateFeedItemSetLinksResponse, + Awaitable[ + feed_item_set_link_service.MutateFeedItemSetLinksResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedItemSetLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/grpc.py new file mode 100644 index 000000000..ff1af429d --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_link_service/transports/grpc.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_link_service +from .base import FeedItemSetLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedItemSetLinkServiceGrpcTransport(FeedItemSetLinkServiceTransport): + """gRPC backend transport for FeedItemSetLinkService. + + Service to manage feed item set links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feed_item_set_links( + self, + ) -> Callable[ + [feed_item_set_link_service.MutateFeedItemSetLinksRequest], + feed_item_set_link_service.MutateFeedItemSetLinksResponse, + ]: + r"""Return a callable for the mutate feed item set links method over gRPC. + + Creates, updates, or removes feed item set links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateFeedItemSetLinksRequest], + ~.MutateFeedItemSetLinksResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feed_item_set_links" not in self._stubs: + self._stubs[ + "mutate_feed_item_set_links" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedItemSetLinkService/MutateFeedItemSetLinks", + request_serializer=feed_item_set_link_service.MutateFeedItemSetLinksRequest.serialize, + response_deserializer=feed_item_set_link_service.MutateFeedItemSetLinksResponse.deserialize, + ) + return self._stubs["mutate_feed_item_set_links"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedItemSetLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_service/__init__.py b/google/ads/googleads/v12/services/services/feed_item_set_service/__init__.py new file mode 100644 index 000000000..740e97dbc --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedItemSetServiceClient + +__all__ = ("FeedItemSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_service/client.py b/google/ads/googleads/v12/services/services/feed_item_set_service/client.py new file mode 100644 index 000000000..197a28440 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_service/client.py @@ -0,0 +1,505 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import FeedItemSetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import FeedItemSetServiceGrpcTransport + + +class FeedItemSetServiceClientMeta(type): + """Metaclass for the FeedItemSetService 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[FeedItemSetServiceTransport]] + _transport_registry["grpc"] = FeedItemSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedItemSetServiceTransport]: + """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 FeedItemSetServiceClient(metaclass=FeedItemSetServiceClientMeta): + """Service to manage feed Item Set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedItemSetServiceClient: 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: + FeedItemSetServiceClient: 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) -> FeedItemSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedItemSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_path( + customer_id: str, feed_id: str, feed_item_set_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set string.""" + return "customers/{customer_id}/feedItemSets/{feed_id}~{feed_item_set_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + ) + + @staticmethod + def parse_feed_item_set_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedItemSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed item set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, FeedItemSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedItemSetServiceTransport): + # transport is a FeedItemSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feed_item_sets( + self, + request: Union[ + feed_item_set_service.MutateFeedItemSetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[feed_item_set_service.FeedItemSetOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_item_set_service.MutateFeedItemSetsResponse: + r"""Creates, updates or removes feed item sets. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedItemSetsRequest, dict]): + The request object. Request message for + [FeedItemSetService.MutateFeedItemSets][google.ads.googleads.v12.services.FeedItemSetService.MutateFeedItemSets]. + customer_id (str): + Required. The ID of the customer + whose feed item sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemSetOperation]): + Required. The list of operations to + perform on individual feed item sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedItemSetsResponse: + Response message for an feed item set + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_item_set_service.MutateFeedItemSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, feed_item_set_service.MutateFeedItemSetsRequest + ): + request = feed_item_set_service.MutateFeedItemSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_feed_item_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedItemSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/__init__.py new file mode 100644 index 000000000..0b3ea9f29 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedItemSetServiceTransport +from .grpc import FeedItemSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedItemSetServiceTransport]] +_transport_registry["grpc"] = FeedItemSetServiceGrpcTransport + +__all__ = ( + "FeedItemSetServiceTransport", + "FeedItemSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/base.py new file mode 100644 index 000000000..1a582a787 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedItemSetServiceTransport(abc.ABC): + """Abstract transport class for FeedItemSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feed_item_sets: gapic_v1.method.wrap_method( + self.mutate_feed_item_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feed_item_sets( + self, + ) -> Callable[ + [feed_item_set_service.MutateFeedItemSetsRequest], + Union[ + feed_item_set_service.MutateFeedItemSetsResponse, + Awaitable[feed_item_set_service.MutateFeedItemSetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedItemSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/grpc.py new file mode 100644 index 000000000..d0afef6f8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_set_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_set_service +from .base import FeedItemSetServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedItemSetServiceGrpcTransport(FeedItemSetServiceTransport): + """gRPC backend transport for FeedItemSetService. + + Service to manage feed Item Set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feed_item_sets( + self, + ) -> Callable[ + [feed_item_set_service.MutateFeedItemSetsRequest], + feed_item_set_service.MutateFeedItemSetsResponse, + ]: + r"""Return a callable for the mutate feed item sets method over gRPC. + + Creates, updates or removes feed item sets. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateFeedItemSetsRequest], + ~.MutateFeedItemSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feed_item_sets" not in self._stubs: + self._stubs[ + "mutate_feed_item_sets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedItemSetService/MutateFeedItemSets", + request_serializer=feed_item_set_service.MutateFeedItemSetsRequest.serialize, + response_deserializer=feed_item_set_service.MutateFeedItemSetsResponse.deserialize, + ) + return self._stubs["mutate_feed_item_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedItemSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_target_service/__init__.py b/google/ads/googleads/v12/services/services/feed_item_target_service/__init__.py new file mode 100644 index 000000000..63611fd94 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_target_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedItemTargetServiceClient + +__all__ = ("FeedItemTargetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_target_service/client.py b/google/ads/googleads/v12/services/services/feed_item_target_service/client.py new file mode 100644 index 000000000..95891f0ef --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_target_service/client.py @@ -0,0 +1,568 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_target_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import FeedItemTargetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import FeedItemTargetServiceGrpcTransport + + +class FeedItemTargetServiceClientMeta(type): + """Metaclass for the FeedItemTargetService 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[FeedItemTargetServiceTransport]] + _transport_registry["grpc"] = FeedItemTargetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedItemTargetServiceTransport]: + """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 FeedItemTargetServiceClient(metaclass=FeedItemTargetServiceClientMeta): + """Service to manage feed item targets.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedItemTargetServiceClient: 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: + FeedItemTargetServiceClient: 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) -> FeedItemTargetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedItemTargetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_path( + customer_id: str, feed_id: str, feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item string.""" + return "customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}".format( + customer_id=customer_id, feed_id=feed_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_path(path: str) -> Dict[str, str]: + """Parses a feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItems/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_target_path( + customer_id: str, + feed_id: str, + feed_item_id: str, + feed_item_target_type: str, + feed_item_target_id: str, + ) -> str: + """Returns a fully-qualified feed_item_target string.""" + return "customers/{customer_id}/feedItemTargets/{feed_id}~{feed_item_id}~{feed_item_target_type}~{feed_item_target_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_id=feed_item_id, + feed_item_target_type=feed_item_target_type, + feed_item_target_id=feed_item_target_id, + ) + + @staticmethod + def parse_feed_item_target_path(path: str) -> Dict[str, str]: + """Parses a feed_item_target path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemTargets/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedItemTargetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed item target 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 (Union[str, FeedItemTargetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedItemTargetServiceTransport): + # transport is a FeedItemTargetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feed_item_targets( + self, + request: Union[ + feed_item_target_service.MutateFeedItemTargetsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + feed_item_target_service.FeedItemTargetOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_item_target_service.MutateFeedItemTargetsResponse: + r"""Creates or removes feed item targets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ + `FeedItemTargetError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedItemTargetsRequest, dict]): + The request object. Request message for + [FeedItemTargetService.MutateFeedItemTargets][google.ads.googleads.v12.services.FeedItemTargetService.MutateFeedItemTargets]. + customer_id (str): + Required. The ID of the customer + whose feed item targets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemTargetOperation]): + Required. The list of operations to + perform on individual feed item targets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedItemTargetsResponse: + Response message for an feed item + target mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_item_target_service.MutateFeedItemTargetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, feed_item_target_service.MutateFeedItemTargetsRequest + ): + request = feed_item_target_service.MutateFeedItemTargetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_feed_item_targets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedItemTargetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_item_target_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/__init__.py new file mode 100644 index 000000000..7fa242ac0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedItemTargetServiceTransport +from .grpc import FeedItemTargetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedItemTargetServiceTransport]] +_transport_registry["grpc"] = FeedItemTargetServiceGrpcTransport + +__all__ = ( + "FeedItemTargetServiceTransport", + "FeedItemTargetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_item_target_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/base.py new file mode 100644 index 000000000..cba43460c --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_target_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedItemTargetServiceTransport(abc.ABC): + """Abstract transport class for FeedItemTargetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feed_item_targets: gapic_v1.method.wrap_method( + self.mutate_feed_item_targets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feed_item_targets( + self, + ) -> Callable[ + [feed_item_target_service.MutateFeedItemTargetsRequest], + Union[ + feed_item_target_service.MutateFeedItemTargetsResponse, + Awaitable[feed_item_target_service.MutateFeedItemTargetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedItemTargetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_item_target_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/grpc.py new file mode 100644 index 000000000..2ad691ad0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_item_target_service/transports/grpc.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_item_target_service +from .base import FeedItemTargetServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedItemTargetServiceGrpcTransport(FeedItemTargetServiceTransport): + """gRPC backend transport for FeedItemTargetService. + + Service to manage feed item targets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feed_item_targets( + self, + ) -> Callable[ + [feed_item_target_service.MutateFeedItemTargetsRequest], + feed_item_target_service.MutateFeedItemTargetsResponse, + ]: + r"""Return a callable for the mutate feed item targets method over gRPC. + + Creates or removes feed item targets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ + `FeedItemTargetError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateFeedItemTargetsRequest], + ~.MutateFeedItemTargetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feed_item_targets" not in self._stubs: + self._stubs[ + "mutate_feed_item_targets" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedItemTargetService/MutateFeedItemTargets", + request_serializer=feed_item_target_service.MutateFeedItemTargetsRequest.serialize, + response_deserializer=feed_item_target_service.MutateFeedItemTargetsResponse.deserialize, + ) + return self._stubs["mutate_feed_item_targets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedItemTargetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_mapping_service/__init__.py b/google/ads/googleads/v12/services/services/feed_mapping_service/__init__.py new file mode 100644 index 000000000..3995567e0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_mapping_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedMappingServiceClient + +__all__ = ("FeedMappingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_mapping_service/client.py b/google/ads/googleads/v12/services/services/feed_mapping_service/client.py new file mode 100644 index 000000000..a9d942dfa --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_mapping_service/client.py @@ -0,0 +1,510 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_mapping_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import FeedMappingServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import FeedMappingServiceGrpcTransport + + +class FeedMappingServiceClientMeta(type): + """Metaclass for the FeedMappingService 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[FeedMappingServiceTransport]] + _transport_registry["grpc"] = FeedMappingServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedMappingServiceTransport]: + """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 FeedMappingServiceClient(metaclass=FeedMappingServiceClientMeta): + """Service to manage feed mappings.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedMappingServiceClient: 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: + FeedMappingServiceClient: 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) -> FeedMappingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedMappingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_mapping_path( + customer_id: str, feed_id: str, feed_mapping_id: str, + ) -> str: + """Returns a fully-qualified feed_mapping string.""" + return "customers/{customer_id}/feedMappings/{feed_id}~{feed_mapping_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_mapping_id=feed_mapping_id, + ) + + @staticmethod + def parse_feed_mapping_path(path: str) -> Dict[str, str]: + """Parses a feed_mapping path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedMappings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedMappingServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed mapping 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 (Union[str, FeedMappingServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedMappingServiceTransport): + # transport is a FeedMappingServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feed_mappings( + self, + request: Union[ + feed_mapping_service.MutateFeedMappingsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[feed_mapping_service.FeedMappingOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_mapping_service.MutateFeedMappingsResponse: + r"""Creates or removes feed mappings. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FeedMappingError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedMappingsRequest, dict]): + The request object. Request message for + [FeedMappingService.MutateFeedMappings][google.ads.googleads.v12.services.FeedMappingService.MutateFeedMappings]. + customer_id (str): + Required. The ID of the customer + whose feed mappings are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedMappingOperation]): + Required. The list of operations to + perform on individual feed mappings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedMappingsResponse: + Response message for a feed mapping + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_mapping_service.MutateFeedMappingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, feed_mapping_service.MutateFeedMappingsRequest + ): + request = feed_mapping_service.MutateFeedMappingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_feed_mappings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedMappingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_mapping_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/__init__.py new file mode 100644 index 000000000..74f4aee51 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedMappingServiceTransport +from .grpc import FeedMappingServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedMappingServiceTransport]] +_transport_registry["grpc"] = FeedMappingServiceGrpcTransport + +__all__ = ( + "FeedMappingServiceTransport", + "FeedMappingServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_mapping_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/base.py new file mode 100644 index 000000000..54c566cd3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_mapping_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedMappingServiceTransport(abc.ABC): + """Abstract transport class for FeedMappingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feed_mappings: gapic_v1.method.wrap_method( + self.mutate_feed_mappings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feed_mappings( + self, + ) -> Callable[ + [feed_mapping_service.MutateFeedMappingsRequest], + Union[ + feed_mapping_service.MutateFeedMappingsResponse, + Awaitable[feed_mapping_service.MutateFeedMappingsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedMappingServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_mapping_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/grpc.py new file mode 100644 index 000000000..2e2fff299 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_mapping_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_mapping_service +from .base import FeedMappingServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedMappingServiceGrpcTransport(FeedMappingServiceTransport): + """gRPC backend transport for FeedMappingService. + + Service to manage feed mappings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feed_mappings( + self, + ) -> Callable[ + [feed_mapping_service.MutateFeedMappingsRequest], + feed_mapping_service.MutateFeedMappingsResponse, + ]: + r"""Return a callable for the mutate feed mappings method over gRPC. + + Creates or removes feed mappings. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FeedMappingError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateFeedMappingsRequest], + ~.MutateFeedMappingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feed_mappings" not in self._stubs: + self._stubs["mutate_feed_mappings"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedMappingService/MutateFeedMappings", + request_serializer=feed_mapping_service.MutateFeedMappingsRequest.serialize, + response_deserializer=feed_mapping_service.MutateFeedMappingsResponse.deserialize, + ) + return self._stubs["mutate_feed_mappings"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedMappingServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_service/__init__.py b/google/ads/googleads/v12/services/services/feed_service/__init__.py new file mode 100644 index 000000000..7d6bdd98b --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 FeedServiceClient + +__all__ = ("FeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_service/client.py b/google/ads/googleads/v12/services/services/feed_service/client.py new file mode 100644 index 000000000..f10b09a0f --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_service/client.py @@ -0,0 +1,483 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import feed_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import FeedServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import FeedServiceGrpcTransport + + +class FeedServiceClientMeta(type): + """Metaclass for the FeedService 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[FeedServiceTransport]] + _transport_registry["grpc"] = FeedServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[FeedServiceTransport]: + """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 FeedServiceClient(metaclass=FeedServiceClientMeta): + """Service to manage feeds.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + FeedServiceClient: 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: + FeedServiceClient: 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) -> FeedServiceTransport: + """Returns the transport used by the client instance. + + Returns: + FeedServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, FeedServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the feed 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 (Union[str, FeedServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, FeedServiceTransport): + # transport is a FeedServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_feeds( + self, + request: Union[feed_service.MutateFeedsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[feed_service.FeedOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> feed_service.MutateFeedsResponse: + r"""Creates, updates, or removes feeds. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FeedError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateFeedsRequest, dict]): + The request object. Request message for + [FeedService.MutateFeeds][google.ads.googleads.v12.services.FeedService.MutateFeeds]. + customer_id (str): + Required. The ID of the customer + whose feeds are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.FeedOperation]): + Required. The list of operations to + perform on individual feeds. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateFeedsResponse: + Response message for an feed mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a feed_service.MutateFeedsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, feed_service.MutateFeedsRequest): + request = feed_service.MutateFeedsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_feeds] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("FeedServiceClient",) diff --git a/google/ads/googleads/v12/services/services/feed_service/transports/__init__.py b/google/ads/googleads/v12/services/services/feed_service/transports/__init__.py new file mode 100644 index 000000000..3a766a595 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 FeedServiceTransport +from .grpc import FeedServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[FeedServiceTransport]] +_transport_registry["grpc"] = FeedServiceGrpcTransport + +__all__ = ( + "FeedServiceTransport", + "FeedServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/feed_service/transports/base.py b/google/ads/googleads/v12/services/services/feed_service/transports/base.py new file mode 100644 index 000000000..e771f4099 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import feed_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class FeedServiceTransport(abc.ABC): + """Abstract transport class for FeedService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_feeds: gapic_v1.method.wrap_method( + self.mutate_feeds, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_feeds( + self, + ) -> Callable[ + [feed_service.MutateFeedsRequest], + Union[ + feed_service.MutateFeedsResponse, + Awaitable[feed_service.MutateFeedsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("FeedServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/feed_service/transports/grpc.py b/google/ads/googleads/v12/services/services/feed_service/transports/grpc.py new file mode 100644 index 000000000..5df200a13 --- /dev/null +++ b/google/ads/googleads/v12/services/services/feed_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import feed_service +from .base import FeedServiceTransport, DEFAULT_CLIENT_INFO + + +class FeedServiceGrpcTransport(FeedServiceTransport): + """gRPC backend transport for FeedService. + + Service to manage feeds. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_feeds( + self, + ) -> Callable[ + [feed_service.MutateFeedsRequest], feed_service.MutateFeedsResponse + ]: + r"""Return a callable for the mutate feeds method over gRPC. + + Creates, updates, or removes feeds. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FeedError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateFeedsRequest], + ~.MutateFeedsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_feeds" not in self._stubs: + self._stubs["mutate_feeds"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.FeedService/MutateFeeds", + request_serializer=feed_service.MutateFeedsRequest.serialize, + response_deserializer=feed_service.MutateFeedsResponse.deserialize, + ) + return self._stubs["mutate_feeds"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("FeedServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/geo_target_constant_service/__init__.py b/google/ads/googleads/v12/services/services/geo_target_constant_service/__init__.py new file mode 100644 index 000000000..873c088db --- /dev/null +++ b/google/ads/googleads/v12/services/services/geo_target_constant_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 GeoTargetConstantServiceClient + +__all__ = ("GeoTargetConstantServiceClient",) diff --git a/google/ads/googleads/v12/services/services/geo_target_constant_service/client.py b/google/ads/googleads/v12/services/services/geo_target_constant_service/client.py new file mode 100644 index 000000000..62f51ae85 --- /dev/null +++ b/google/ads/googleads/v12/services/services/geo_target_constant_service/client.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import geo_target_constant_service +from .transports.base import ( + GeoTargetConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import GeoTargetConstantServiceGrpcTransport + + +class GeoTargetConstantServiceClientMeta(type): + """Metaclass for the GeoTargetConstantService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GeoTargetConstantServiceTransport]] + _transport_registry["grpc"] = GeoTargetConstantServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[GeoTargetConstantServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GeoTargetConstantServiceClient( + metaclass=GeoTargetConstantServiceClientMeta +): + """Service to fetch geo target constants.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GeoTargetConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GeoTargetConstantServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, GeoTargetConstantServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the geo target constant service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, GeoTargetConstantServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, GeoTargetConstantServiceTransport): + # transport is a GeoTargetConstantServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def suggest_geo_target_constants( + self, + request: Union[ + geo_target_constant_service.SuggestGeoTargetConstantsRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> geo_target_constant_service.SuggestGeoTargetConstantsResponse: + r"""Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.SuggestGeoTargetConstantsRequest, dict]): + The request object. Request message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v12.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.SuggestGeoTargetConstantsResponse: + Response message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v12.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a geo_target_constant_service.SuggestGeoTargetConstantsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + geo_target_constant_service.SuggestGeoTargetConstantsRequest, + ): + request = geo_target_constant_service.SuggestGeoTargetConstantsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_geo_target_constants + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("GeoTargetConstantServiceClient",) diff --git a/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/__init__.py b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/__init__.py new file mode 100644 index 000000000..8b179c311 --- /dev/null +++ b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 GeoTargetConstantServiceTransport +from .grpc import GeoTargetConstantServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[GeoTargetConstantServiceTransport]] +_transport_registry["grpc"] = GeoTargetConstantServiceGrpcTransport + +__all__ = ( + "GeoTargetConstantServiceTransport", + "GeoTargetConstantServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/base.py b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/base.py new file mode 100644 index 000000000..d4257c763 --- /dev/null +++ b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import geo_target_constant_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class GeoTargetConstantServiceTransport(abc.ABC): + """Abstract transport class for GeoTargetConstantService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_geo_target_constants: gapic_v1.method.wrap_method( + self.suggest_geo_target_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_geo_target_constants( + self, + ) -> Callable[ + [geo_target_constant_service.SuggestGeoTargetConstantsRequest], + Union[ + geo_target_constant_service.SuggestGeoTargetConstantsResponse, + Awaitable[ + geo_target_constant_service.SuggestGeoTargetConstantsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("GeoTargetConstantServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/grpc.py b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/grpc.py new file mode 100644 index 000000000..dc0c99ab2 --- /dev/null +++ b/google/ads/googleads/v12/services/services/geo_target_constant_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import geo_target_constant_service +from .base import GeoTargetConstantServiceTransport, DEFAULT_CLIENT_INFO + + +class GeoTargetConstantServiceGrpcTransport(GeoTargetConstantServiceTransport): + """gRPC backend transport for GeoTargetConstantService. + + Service to fetch geo target constants. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def suggest_geo_target_constants( + self, + ) -> Callable[ + [geo_target_constant_service.SuggestGeoTargetConstantsRequest], + geo_target_constant_service.SuggestGeoTargetConstantsResponse, + ]: + r"""Return a callable for the suggest geo target constants method over gRPC. + + Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestGeoTargetConstantsRequest], + ~.SuggestGeoTargetConstantsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_geo_target_constants" not in self._stubs: + self._stubs[ + "suggest_geo_target_constants" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.GeoTargetConstantService/SuggestGeoTargetConstants", + request_serializer=geo_target_constant_service.SuggestGeoTargetConstantsRequest.serialize, + response_deserializer=geo_target_constant_service.SuggestGeoTargetConstantsResponse.deserialize, + ) + return self._stubs["suggest_geo_target_constants"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("GeoTargetConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/__init__.py b/google/ads/googleads/v12/services/services/google_ads_field_service/__init__.py new file mode 100644 index 000000000..56381058c --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 GoogleAdsFieldServiceClient + +__all__ = ("GoogleAdsFieldServiceClient",) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/client.py b/google/ads/googleads/v12/services/services/google_ads_field_service/client.py new file mode 100644 index 000000000..a34c3f219 --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/client.py @@ -0,0 +1,561 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import google_ads_field +from google.ads.googleads.v12.services.services.google_ads_field_service import ( + pagers, +) +from google.ads.googleads.v12.services.types import google_ads_field_service +from .transports.base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GoogleAdsFieldServiceGrpcTransport + + +class GoogleAdsFieldServiceClientMeta(type): + """Metaclass for the GoogleAdsFieldService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GoogleAdsFieldServiceTransport]] + _transport_registry["grpc"] = GoogleAdsFieldServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[GoogleAdsFieldServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GoogleAdsFieldServiceClient(metaclass=GoogleAdsFieldServiceClientMeta): + """Service to fetch Google Ads API fields.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GoogleAdsFieldServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsFieldServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def google_ads_field_path(google_ads_field: str,) -> str: + """Returns a fully-qualified google_ads_field string.""" + return "googleAdsFields/{google_ads_field}".format( + google_ads_field=google_ads_field, + ) + + @staticmethod + def parse_google_ads_field_path(path: str) -> Dict[str, str]: + """Parses a google_ads_field path into its component segments.""" + m = re.match(r"^googleAdsFields/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, GoogleAdsFieldServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads field service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, GoogleAdsFieldServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, GoogleAdsFieldServiceTransport): + # transport is a GoogleAdsFieldServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def get_google_ads_field( + self, + request: Union[ + google_ads_field_service.GetGoogleAdsFieldRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> google_ads_field.GoogleAdsField: + r"""Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GetGoogleAdsFieldRequest, dict]): + The request object. Request message for + [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v12.services.GoogleAdsFieldService.GetGoogleAdsField]. + resource_name (str): + Required. The resource name of the + field to get. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.resources.types.GoogleAdsField: + A field or resource (artifact) used + by GoogleAdsService. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a google_ads_field_service.GetGoogleAdsFieldRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, google_ads_field_service.GetGoogleAdsFieldRequest + ): + request = google_ads_field_service.GetGoogleAdsFieldRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_google_ads_field + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def search_google_ads_fields( + self, + request: Union[ + google_ads_field_service.SearchGoogleAdsFieldsRequest, dict + ] = None, + *, + query: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchGoogleAdsFieldsPager: + r"""Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.SearchGoogleAdsFieldsRequest, dict]): + The request object. Request message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v12.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.google_ads_field_service.pagers.SearchGoogleAdsFieldsPager: + Response message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v12.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([query]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a google_ads_field_service.SearchGoogleAdsFieldsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, google_ads_field_service.SearchGoogleAdsFieldsRequest + ): + request = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.search_google_ads_fields + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchGoogleAdsFieldsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("GoogleAdsFieldServiceClient",) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/pagers.py b/google/ads/googleads/v12/services/services/google_ads_field_service/pagers.py new file mode 100644 index 000000000..5f4d92c8b --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/pagers.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.resources.types import google_ads_field +from google.ads.googleads.v12.services.types import google_ads_field_service + + +class SearchGoogleAdsFieldsPager: + """A pager for iterating through ``search_google_ads_fields`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.SearchGoogleAdsFieldsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``SearchGoogleAdsFields`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.SearchGoogleAdsFieldsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., google_ads_field_service.SearchGoogleAdsFieldsResponse + ], + request: google_ads_field_service.SearchGoogleAdsFieldsRequest, + response: google_ads_field_service.SearchGoogleAdsFieldsResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.SearchGoogleAdsFieldsRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.SearchGoogleAdsFieldsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterable[google_ads_field_service.SearchGoogleAdsFieldsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__(self) -> Iterator[google_ads_field.GoogleAdsField]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/transports/__init__.py b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/__init__.py new file mode 100644 index 000000000..0e9210c55 --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 GoogleAdsFieldServiceTransport +from .grpc import GoogleAdsFieldServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[GoogleAdsFieldServiceTransport]] +_transport_registry["grpc"] = GoogleAdsFieldServiceGrpcTransport + +__all__ = ( + "GoogleAdsFieldServiceTransport", + "GoogleAdsFieldServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/transports/base.py b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/base.py new file mode 100644 index 000000000..87457bedb --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/base.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.resources.types import google_ads_field +from google.ads.googleads.v12.services.types import google_ads_field_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class GoogleAdsFieldServiceTransport(abc.ABC): + """Abstract transport class for GoogleAdsFieldService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_google_ads_field: gapic_v1.method.wrap_method( + self.get_google_ads_field, + default_timeout=None, + client_info=client_info, + ), + self.search_google_ads_fields: gapic_v1.method.wrap_method( + self.search_google_ads_fields, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def get_google_ads_field( + self, + ) -> Callable[ + [google_ads_field_service.GetGoogleAdsFieldRequest], + Union[ + google_ads_field.GoogleAdsField, + Awaitable[google_ads_field.GoogleAdsField], + ], + ]: + raise NotImplementedError() + + @property + def search_google_ads_fields( + self, + ) -> Callable[ + [google_ads_field_service.SearchGoogleAdsFieldsRequest], + Union[ + google_ads_field_service.SearchGoogleAdsFieldsResponse, + Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("GoogleAdsFieldServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/google_ads_field_service/transports/grpc.py b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/grpc.py new file mode 100644 index 000000000..e330749fa --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_field_service/transports/grpc.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.resources.types import google_ads_field +from google.ads.googleads.v12.services.types import google_ads_field_service +from .base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO + + +class GoogleAdsFieldServiceGrpcTransport(GoogleAdsFieldServiceTransport): + """gRPC backend transport for GoogleAdsFieldService. + + Service to fetch Google Ads API fields. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def get_google_ads_field( + self, + ) -> Callable[ + [google_ads_field_service.GetGoogleAdsFieldRequest], + google_ads_field.GoogleAdsField, + ]: + r"""Return a callable for the get google ads field method over gRPC. + + Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetGoogleAdsFieldRequest], + ~.GoogleAdsField]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_google_ads_field" not in self._stubs: + self._stubs["get_google_ads_field"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.GoogleAdsFieldService/GetGoogleAdsField", + request_serializer=google_ads_field_service.GetGoogleAdsFieldRequest.serialize, + response_deserializer=google_ads_field.GoogleAdsField.deserialize, + ) + return self._stubs["get_google_ads_field"] + + @property + def search_google_ads_fields( + self, + ) -> Callable[ + [google_ads_field_service.SearchGoogleAdsFieldsRequest], + google_ads_field_service.SearchGoogleAdsFieldsResponse, + ]: + r"""Return a callable for the search google ads fields method over gRPC. + + Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsFieldsRequest], + ~.SearchGoogleAdsFieldsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_google_ads_fields" not in self._stubs: + self._stubs[ + "search_google_ads_fields" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.GoogleAdsFieldService/SearchGoogleAdsFields", + request_serializer=google_ads_field_service.SearchGoogleAdsFieldsRequest.serialize, + response_deserializer=google_ads_field_service.SearchGoogleAdsFieldsResponse.deserialize, + ) + return self._stubs["search_google_ads_fields"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("GoogleAdsFieldServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/__init__.py b/google/ads/googleads/v12/services/services/google_ads_service/__init__.py new file mode 100644 index 000000000..34ecec17f --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 GoogleAdsServiceClient + +__all__ = ("GoogleAdsServiceClient",) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/client.py b/google/ads/googleads/v12/services/services/google_ads_service/client.py new file mode 100644 index 000000000..78e850051 --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/client.py @@ -0,0 +1,3662 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Iterable, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.services.google_ads_service import pagers +from google.ads.googleads.v12.services.types import google_ads_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GoogleAdsServiceGrpcTransport + + +class GoogleAdsServiceClientMeta(type): + """Metaclass for the GoogleAdsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GoogleAdsServiceTransport]] + _transport_registry["grpc"] = GoogleAdsServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[GoogleAdsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GoogleAdsServiceClient(metaclass=GoogleAdsServiceClientMeta): + """Service to fetch data and metrics across resources.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GoogleAdsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_path(customer_id: str, account_budget_id: str,) -> str: + """Returns a fully-qualified account_budget string.""" + return "customers/{customer_id}/accountBudgets/{account_budget_id}".format( + customer_id=customer_id, account_budget_id=account_budget_id, + ) + + @staticmethod + def parse_account_budget_path(path: str) -> Dict[str, str]: + """Parses a account_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_proposal_path( + customer_id: str, account_budget_proposal_id: str, + ) -> str: + """Returns a fully-qualified account_budget_proposal string.""" + return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( + customer_id=customer_id, + account_budget_proposal_id=account_budget_proposal_id, + ) + + @staticmethod + def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: + """Parses a account_budget_proposal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_link_path(customer_id: str, account_link_id: str,) -> str: + """Returns a fully-qualified account_link string.""" + return "customers/{customer_id}/accountLinks/{account_link_id}".format( + customer_id=customer_id, account_link_id=account_link_id, + ) + + @staticmethod + def parse_account_link_path(path: str) -> Dict[str, str]: + """Parses a account_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_path(customer_id: str, ad_id: str,) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path(customer_id: str, ad_group_id: str,) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, ad_group_id: str, ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_asset_combination_view_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + asset_combination_id_low: str, + asset_combination_id_high: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_asset_combination_view string.""" + return "customers/{customer_id}/adGroupAdAssetCombinationViews/{ad_group_id}~{ad_id}~{asset_combination_id_low}~{asset_combination_id_high}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + asset_combination_id_low=asset_combination_id_low, + asset_combination_id_high=asset_combination_id_high, + ) + + @staticmethod + def parse_ad_group_ad_asset_combination_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a ad_group_ad_asset_combination_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdAssetCombinationViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_asset_view_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_asset_view string.""" + return "customers/{customer_id}/adGroupAdAssetViews/{ad_group_id}~{ad_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_ad_asset_view_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_asset_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, ad_group_id: str, ad_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, ad_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_set_path( + customer_id: str, ad_group_id: str, asset_set_id: str, + ) -> str: + """Returns a fully-qualified ad_group_asset_set string.""" + return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_audience_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_audience_view string.""" + return "customers/{customer_id}/adGroupAudienceViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_audience_view_path(path: str) -> Dict[str, str]: + """Parses a ad_group_audience_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAudienceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, ad_group_id: str, criterion_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_simulation_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_simulation string.""" + return "customers/{customer_id}/adGroupCriterionSimulations/{ad_group_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_ad_group_criterion_simulation_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, ad_group_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_extension_setting_path( + customer_id: str, ad_group_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified ad_group_extension_setting string.""" + return "customers/{customer_id}/adGroupExtensionSettings/{ad_group_id}~{extension_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_ad_group_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a ad_group_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_feed_path( + customer_id: str, ad_group_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified ad_group_feed string.""" + return "customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, feed_id=feed_id, + ) + + @staticmethod + def parse_ad_group_feed_path(path: str) -> Dict[str, str]: + """Parses a ad_group_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, ad_group_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, ad_group_id=ad_group_id, label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_simulation_path( + customer_id: str, + ad_group_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified ad_group_simulation string.""" + return "customers/{customer_id}/adGroupSimulations/{ad_group_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_ad_group_simulation_path(path: str) -> Dict[str, str]: + """Parses a ad_group_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_schedule_view_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_schedule_view string.""" + return "customers/{customer_id}/adScheduleViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_schedule_view_path(path: str) -> Dict[str, str]: + """Parses a ad_schedule_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adScheduleViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def age_range_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified age_range_view string.""" + return "customers/{customer_id}/ageRangeViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_age_range_view_path(path: str) -> Dict[str, str]: + """Parses a age_range_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ageRangeViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path(customer_id: str, asset_id: str,) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_field_type_view_path(customer_id: str, field_type: str,) -> str: + """Returns a fully-qualified asset_field_type_view string.""" + return "customers/{customer_id}/assetFieldTypeViews/{field_type}".format( + customer_id=customer_id, field_type=field_type, + ) + + @staticmethod + def parse_asset_field_type_view_path(path: str) -> Dict[str, str]: + """Parses a asset_field_type_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetFieldTypeViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path(customer_id: str, asset_group_id: str,) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, asset_group_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, asset_group_id: str, listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_product_group_view_path( + customer_id: str, asset_group_id: str, listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_product_group_view string.""" + return "customers/{customer_id}/assetGroupProductGroupViews/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_product_group_view_path(path: str) -> Dict[str, str]: + """Parses a asset_group_product_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupProductGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, asset_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, asset_set_id: str, asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_type_view_path(customer_id: str, asset_set_type: str,) -> str: + """Returns a fully-qualified asset_set_type_view string.""" + return "customers/{customer_id}/assetSetTypeViews/{asset_set_type}".format( + customer_id=customer_id, asset_set_type=asset_set_type, + ) + + @staticmethod + def parse_asset_set_type_view_path(path: str) -> Dict[str, str]: + """Parses a asset_set_type_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetTypeViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_path(customer_id: str, audience_id: str,) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def batch_job_path(customer_id: str, batch_job_id: str,) -> str: + """Returns a fully-qualified batch_job string.""" + return "customers/{customer_id}/batchJobs/{batch_job_id}".format( + customer_id=customer_id, batch_job_id=batch_job_id, + ) + + @staticmethod + def parse_batch_job_path(path: str) -> Dict[str, str]: + """Parses a batch_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/batchJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_simulation_path( + customer_id: str, + bidding_strategy_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified bidding_strategy_simulation string.""" + return "customers/{customer_id}/biddingStrategySimulations/{bidding_strategy_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_bidding_strategy_simulation_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategySimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def billing_setup_path(customer_id: str, billing_setup_id: str,) -> str: + """Returns a fully-qualified billing_setup string.""" + return "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, billing_setup_id=billing_setup_id, + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def call_view_path(customer_id: str, call_detail_id: str,) -> str: + """Returns a fully-qualified call_view string.""" + return "customers/{customer_id}/callViews/{call_detail_id}".format( + customer_id=customer_id, call_detail_id=call_detail_id, + ) + + @staticmethod + def parse_call_view_path(path: str) -> Dict[str, str]: + """Parses a call_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/callViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, campaign_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, campaign_id: str, asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_audience_view_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_audience_view string.""" + return "customers/{customer_id}/campaignAudienceViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_audience_view_path(path: str) -> Dict[str, str]: + """Parses a campaign_audience_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAudienceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path(customer_id: str, campaign_budget_id: str,) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, campaign_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_simulation_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified campaign_criterion_simulation string.""" + return "customers/{customer_id}/campaignCriterionSimulations/{campaign_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_campaign_criterion_simulation_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriterionSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, campaign_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, base_campaign_id: str, draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_extension_setting_path( + customer_id: str, campaign_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified campaign_extension_setting string.""" + return "customers/{customer_id}/campaignExtensionSettings/{campaign_id}~{extension_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + extension_type=extension_type, + ) + + @staticmethod + def parse_campaign_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a campaign_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignExtensionSettings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_feed_path( + customer_id: str, campaign_id: str, feed_id: str, + ) -> str: + """Returns a fully-qualified campaign_feed string.""" + return "customers/{customer_id}/campaignFeeds/{campaign_id}~{feed_id}".format( + customer_id=customer_id, campaign_id=campaign_id, feed_id=feed_id, + ) + + @staticmethod + def parse_campaign_feed_path(path: str) -> Dict[str, str]: + """Parses a campaign_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignFeeds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path(customer_id: str, campaign_group_id: str,) -> str: + """Returns a fully-qualified campaign_group string.""" + return "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, campaign_group_id=campaign_group_id, + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, campaign_id: str, label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, campaign_id=campaign_id, label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, campaign_id: str, shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_simulation_path( + customer_id: str, + campaign_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified campaign_simulation string.""" + return "customers/{customer_id}/campaignSimulations/{campaign_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_campaign_simulation_path(path: str) -> Dict[str, str]: + """Parses a campaign_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def carrier_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified carrier_constant string.""" + return "carrierConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_carrier_constant_path(path: str) -> Dict[str, str]: + """Parses a carrier_constant path into its component segments.""" + m = re.match(r"^carrierConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def change_event_path( + customer_id: str, + timestamp_micros: str, + command_index: str, + mutate_index: str, + ) -> str: + """Returns a fully-qualified change_event string.""" + return "customers/{customer_id}/changeEvents/{timestamp_micros}~{command_index}~{mutate_index}".format( + customer_id=customer_id, + timestamp_micros=timestamp_micros, + command_index=command_index, + mutate_index=mutate_index, + ) + + @staticmethod + def parse_change_event_path(path: str) -> Dict[str, str]: + """Parses a change_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/changeEvents/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def change_status_path(customer_id: str, change_status_id: str,) -> str: + """Returns a fully-qualified change_status string.""" + return "customers/{customer_id}/changeStatus/{change_status_id}".format( + customer_id=customer_id, change_status_id=change_status_id, + ) + + @staticmethod + def parse_change_status_path(path: str) -> Dict[str, str]: + """Parses a change_status path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/changeStatus/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def click_view_path(customer_id: str, date: str, gclid: str,) -> str: + """Returns a fully-qualified click_view string.""" + return "customers/{customer_id}/clickViews/{date}~{gclid}".format( + customer_id=customer_id, date=date, gclid=gclid, + ) + + @staticmethod + def parse_click_view_path(path: str) -> Dict[str, str]: + """Parses a click_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/clickViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def combined_audience_path( + customer_id: str, combined_audience_id: str, + ) -> str: + """Returns a fully-qualified combined_audience string.""" + return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( + customer_id=customer_id, combined_audience_id=combined_audience_id, + ) + + @staticmethod + def parse_combined_audience_path(path: str) -> Dict[str, str]: + """Parses a combined_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def currency_constant_path(code: str,) -> str: + """Returns a fully-qualified currency_constant string.""" + return "currencyConstants/{code}".format(code=code,) + + @staticmethod + def parse_currency_constant_path(path: str) -> Dict[str, str]: + """Parses a currency_constant path into its component segments.""" + m = re.match(r"^currencyConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def custom_audience_path(customer_id: str, custom_audience_id: str,) -> str: + """Returns a fully-qualified custom_audience string.""" + return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( + customer_id=customer_id, custom_audience_id=custom_audience_id, + ) + + @staticmethod + def parse_custom_audience_path(path: str) -> Dict[str, str]: + """Parses a custom_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path(customer_id: str, goal_id: str,) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, asset_id: str, field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, asset_id=asset_id, field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_set_path(customer_id: str, asset_set_id: str,) -> str: + """Returns a fully-qualified customer_asset_set string.""" + return "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( + customer_id=customer_id, asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_customer_asset_set_path(path: str) -> Dict[str, str]: + """Parses a customer_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_path(customer_id: str, client_customer_id: str,) -> str: + """Returns a fully-qualified customer_client string.""" + return "customers/{customer_id}/customerClients/{client_customer_id}".format( + customer_id=customer_id, client_customer_id=client_customer_id, + ) + + @staticmethod + def parse_customer_client_path(path: str) -> Dict[str, str]: + """Parses a customer_client path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClients/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_link_path( + customer_id: str, client_customer_id: str, manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_client_link string.""" + return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + client_customer_id=client_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_client_link_path(path: str) -> Dict[str, str]: + """Parses a customer_client_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, category: str, source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, category=category, source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_customizer_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_extension_setting_path( + customer_id: str, extension_type: str, + ) -> str: + """Returns a fully-qualified customer_extension_setting string.""" + return "customers/{customer_id}/customerExtensionSettings/{extension_type}".format( + customer_id=customer_id, extension_type=extension_type, + ) + + @staticmethod + def parse_customer_extension_setting_path(path: str) -> Dict[str, str]: + """Parses a customer_extension_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerExtensionSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified customer_feed string.""" + return "customers/{customer_id}/customerFeeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_customer_feed_path(path: str) -> Dict[str, str]: + """Parses a customer_feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerFeeds/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_manager_link_path( + customer_id: str, manager_customer_id: str, manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_manager_link string.""" + return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + manager_customer_id=manager_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_manager_link_path(path: str) -> Dict[str, str]: + """Parses a customer_manager_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_user_access_path(customer_id: str, user_id: str,) -> str: + """Returns a fully-qualified customer_user_access string.""" + return "customers/{customer_id}/customerUserAccesses/{user_id}".format( + customer_id=customer_id, user_id=user_id, + ) + + @staticmethod + def parse_customer_user_access_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_user_access_invitation_path( + customer_id: str, invitation_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access_invitation string.""" + return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( + customer_id=customer_id, invitation_id=invitation_id, + ) + + @staticmethod + def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_interest_path(customer_id: str, custom_interest_id: str,) -> str: + """Returns a fully-qualified custom_interest string.""" + return "customers/{customer_id}/customInterests/{custom_interest_id}".format( + customer_id=customer_id, custom_interest_id=custom_interest_id, + ) + + @staticmethod + def parse_custom_interest_path(path: str) -> Dict[str, str]: + """Parses a custom_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detailed_demographic_path( + customer_id: str, detailed_demographic_id: str, + ) -> str: + """Returns a fully-qualified detailed_demographic string.""" + return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( + customer_id=customer_id, + detailed_demographic_id=detailed_demographic_id, + ) + + @staticmethod + def parse_detailed_demographic_path(path: str) -> Dict[str, str]: + """Parses a detailed_demographic path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detail_placement_view_path( + customer_id: str, ad_group_id: str, base64_placement: str, + ) -> str: + """Returns a fully-qualified detail_placement_view string.""" + return "customers/{customer_id}/detailPlacementViews/{ad_group_id}~{base64_placement}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + base64_placement=base64_placement, + ) + + @staticmethod + def parse_detail_placement_view_path(path: str) -> Dict[str, str]: + """Parses a detail_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def display_keyword_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified display_keyword_view string.""" + return "customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_display_keyword_view_path(path: str) -> Dict[str, str]: + """Parses a display_keyword_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/displayKeywordViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def distance_view_path( + customer_id: str, placeholder_chain_id: str, distance_bucket: str, + ) -> str: + """Returns a fully-qualified distance_view string.""" + return "customers/{customer_id}/distanceViews/{placeholder_chain_id}~{distance_bucket}".format( + customer_id=customer_id, + placeholder_chain_id=placeholder_chain_id, + distance_bucket=distance_bucket, + ) + + @staticmethod + def parse_distance_view_path(path: str) -> Dict[str, str]: + """Parses a distance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/distanceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def domain_category_path( + customer_id: str, + campaign_id: str, + base64_category: str, + language_code: str, + ) -> str: + """Returns a fully-qualified domain_category string.""" + return "customers/{customer_id}/domainCategories/{campaign_id}~{base64_category}~{language_code}".format( + customer_id=customer_id, + campaign_id=campaign_id, + base64_category=base64_category, + language_code=language_code, + ) + + @staticmethod + def parse_domain_category_path(path: str) -> Dict[str, str]: + """Parses a domain_category path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/domainCategories/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def dynamic_search_ads_search_term_view_path( + customer_id: str, + ad_group_id: str, + search_term_fingerprint: str, + headline_fingerprint: str, + landing_page_fingerprint: str, + page_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified dynamic_search_ads_search_term_view string.""" + return "customers/{customer_id}/dynamicSearchAdsSearchTermViews/{ad_group_id}~{search_term_fingerprint}~{headline_fingerprint}~{landing_page_fingerprint}~{page_url_fingerprint}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + search_term_fingerprint=search_term_fingerprint, + headline_fingerprint=headline_fingerprint, + landing_page_fingerprint=landing_page_fingerprint, + page_url_fingerprint=page_url_fingerprint, + ) + + @staticmethod + def parse_dynamic_search_ads_search_term_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a dynamic_search_ads_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/dynamicSearchAdsSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def expanded_landing_page_view_path( + customer_id: str, expanded_final_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified expanded_landing_page_view string.""" + return "customers/{customer_id}/expandedLandingPageViews/{expanded_final_url_fingerprint}".format( + customer_id=customer_id, + expanded_final_url_fingerprint=expanded_final_url_fingerprint, + ) + + @staticmethod + def parse_expanded_landing_page_view_path(path: str) -> Dict[str, str]: + """Parses a expanded_landing_page_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/expandedLandingPageViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(customer_id: str, trial_id: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, trial_id: str, trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def extension_feed_item_path(customer_id: str, feed_item_id: str,) -> str: + """Returns a fully-qualified extension_feed_item string.""" + return "customers/{customer_id}/extensionFeedItems/{feed_item_id}".format( + customer_id=customer_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_extension_feed_item_path(path: str) -> Dict[str, str]: + """Parses a extension_feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/extensionFeedItems/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_path(customer_id: str, feed_id: str,) -> str: + """Returns a fully-qualified feed string.""" + return "customers/{customer_id}/feeds/{feed_id}".format( + customer_id=customer_id, feed_id=feed_id, + ) + + @staticmethod + def parse_feed_path(path: str) -> Dict[str, str]: + """Parses a feed path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feeds/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_path( + customer_id: str, feed_id: str, feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item string.""" + return "customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}".format( + customer_id=customer_id, feed_id=feed_id, feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_path(path: str) -> Dict[str, str]: + """Parses a feed_item path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItems/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_path( + customer_id: str, feed_id: str, feed_item_set_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set string.""" + return "customers/{customer_id}/feedItemSets/{feed_id}~{feed_item_set_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + ) + + @staticmethod + def parse_feed_item_set_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_set_link_path( + customer_id: str, + feed_id: str, + feed_item_set_id: str, + feed_item_id: str, + ) -> str: + """Returns a fully-qualified feed_item_set_link string.""" + return "customers/{customer_id}/feedItemSetLinks/{feed_id}~{feed_item_set_id}~{feed_item_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_set_id=feed_item_set_id, + feed_item_id=feed_item_id, + ) + + @staticmethod + def parse_feed_item_set_link_path(path: str) -> Dict[str, str]: + """Parses a feed_item_set_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemSetLinks/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_item_target_path( + customer_id: str, + feed_id: str, + feed_item_id: str, + feed_item_target_type: str, + feed_item_target_id: str, + ) -> str: + """Returns a fully-qualified feed_item_target string.""" + return "customers/{customer_id}/feedItemTargets/{feed_id}~{feed_item_id}~{feed_item_target_type}~{feed_item_target_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_item_id=feed_item_id, + feed_item_target_type=feed_item_target_type, + feed_item_target_id=feed_item_target_id, + ) + + @staticmethod + def parse_feed_item_target_path(path: str) -> Dict[str, str]: + """Parses a feed_item_target path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedItemTargets/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_mapping_path( + customer_id: str, feed_id: str, feed_mapping_id: str, + ) -> str: + """Returns a fully-qualified feed_mapping string.""" + return "customers/{customer_id}/feedMappings/{feed_id}~{feed_mapping_id}".format( + customer_id=customer_id, + feed_id=feed_id, + feed_mapping_id=feed_mapping_id, + ) + + @staticmethod + def parse_feed_mapping_path(path: str) -> Dict[str, str]: + """Parses a feed_mapping path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedMappings/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def feed_placeholder_view_path( + customer_id: str, placeholder_type: str, + ) -> str: + """Returns a fully-qualified feed_placeholder_view string.""" + return "customers/{customer_id}/feedPlaceholderViews/{placeholder_type}".format( + customer_id=customer_id, placeholder_type=placeholder_type, + ) + + @staticmethod + def parse_feed_placeholder_view_path(path: str) -> Dict[str, str]: + """Parses a feed_placeholder_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/feedPlaceholderViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def gender_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified gender_view string.""" + return "customers/{customer_id}/genderViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_gender_view_path(path: str) -> Dict[str, str]: + """Parses a gender_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/genderViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geographic_view_path( + customer_id: str, country_criterion_id: str, location_type: str, + ) -> str: + """Returns a fully-qualified geographic_view string.""" + return "customers/{customer_id}/geographicViews/{country_criterion_id}~{location_type}".format( + customer_id=customer_id, + country_criterion_id=country_criterion_id, + location_type=location_type, + ) + + @staticmethod + def parse_geographic_view_path(path: str) -> Dict[str, str]: + """Parses a geographic_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/geographicViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def group_placement_view_path( + customer_id: str, ad_group_id: str, base64_placement: str, + ) -> str: + """Returns a fully-qualified group_placement_view string.""" + return "customers/{customer_id}/groupPlacementViews/{ad_group_id}~{base64_placement}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + base64_placement=base64_placement, + ) + + @staticmethod + def parse_group_placement_view_path(path: str) -> Dict[str, str]: + """Parses a group_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/groupPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_group_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified hotel_group_view string.""" + return "customers/{customer_id}/hotelGroupViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_hotel_group_view_path(path: str) -> Dict[str, str]: + """Parses a hotel_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_performance_view_path(customer_id: str,) -> str: + """Returns a fully-qualified hotel_performance_view string.""" + return "customers/{customer_id}/hotelPerformanceView".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_hotel_performance_view_path(path: str) -> Dict[str, str]: + """Parses a hotel_performance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelPerformanceView$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_reconciliation_path(customer_id: str, commission_id: str,) -> str: + """Returns a fully-qualified hotel_reconciliation string.""" + return "customers/{customer_id}/hotelReconciliations/{commission_id}".format( + customer_id=customer_id, commission_id=commission_id, + ) + + @staticmethod + def parse_hotel_reconciliation_path(path: str) -> Dict[str, str]: + """Parses a hotel_reconciliation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelReconciliations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def income_range_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified income_range_view string.""" + return "customers/{customer_id}/incomeRangeViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_income_range_view_path(path: str) -> Dict[str, str]: + """Parses a income_range_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/incomeRangeViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path(customer_id: str, keyword_plan_id: str,) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified keyword_view string.""" + return "customers/{customer_id}/keywordViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_keyword_view_path(path: str) -> Dict[str, str]: + """Parses a keyword_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def landing_page_view_path( + customer_id: str, unexpanded_final_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified landing_page_view string.""" + return "customers/{customer_id}/landingPageViews/{unexpanded_final_url_fingerprint}".format( + customer_id=customer_id, + unexpanded_final_url_fingerprint=unexpanded_final_url_fingerprint, + ) + + @staticmethod + def parse_landing_page_view_path(path: str) -> Dict[str, str]: + """Parses a landing_page_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/landingPageViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def lead_form_submission_data_path( + customer_id: str, lead_form_user_submission_id: str, + ) -> str: + """Returns a fully-qualified lead_form_submission_data string.""" + return "customers/{customer_id}/leadFormSubmissionData/{lead_form_user_submission_id}".format( + customer_id=customer_id, + lead_form_user_submission_id=lead_form_user_submission_id, + ) + + @staticmethod + def parse_lead_form_submission_data_path(path: str) -> Dict[str, str]: + """Parses a lead_form_submission_data path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/leadFormSubmissionData/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def life_event_path(customer_id: str, life_event_id: str,) -> str: + """Returns a fully-qualified life_event string.""" + return "customers/{customer_id}/lifeEvents/{life_event_id}".format( + customer_id=customer_id, life_event_id=life_event_id, + ) + + @staticmethod + def parse_life_event_path(path: str) -> Dict[str, str]: + """Parses a life_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def location_view_path( + customer_id: str, campaign_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified location_view string.""" + return "customers/{customer_id}/locationViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_location_view_path(path: str) -> Dict[str, str]: + """Parses a location_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/locationViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def managed_placement_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified managed_placement_view string.""" + return "customers/{customer_id}/managedPlacementViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_managed_placement_view_path(path: str) -> Dict[str, str]: + """Parses a managed_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/managedPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def media_file_path(customer_id: str, media_file_id: str,) -> str: + """Returns a fully-qualified media_file string.""" + return "customers/{customer_id}/mediaFiles/{media_file_id}".format( + customer_id=customer_id, media_file_id=media_file_id, + ) + + @staticmethod + def parse_media_file_path(path: str) -> Dict[str, str]: + """Parses a media_file path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/mediaFiles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path(mobile_app_category_id: str,) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified mobile_device_constant string.""" + return "mobileDeviceConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_constant path into its component segments.""" + m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def offline_user_data_job_path( + customer_id: str, offline_user_data_update_id: str, + ) -> str: + """Returns a fully-qualified offline_user_data_job string.""" + return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( + customer_id=customer_id, + offline_user_data_update_id=offline_user_data_update_id, + ) + + @staticmethod + def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: + """Parses a offline_user_data_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def operating_system_version_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified operating_system_version_constant string.""" + return "operatingSystemVersionConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_operating_system_version_constant_path( + path: str, + ) -> Dict[str, str]: + """Parses a operating_system_version_constant path into its component segments.""" + m = re.match( + r"^operatingSystemVersionConstants/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def paid_organic_search_term_view_path( + customer_id: str, + campaign_id: str, + ad_group_id: str, + base64_search_term: str, + ) -> str: + """Returns a fully-qualified paid_organic_search_term_view string.""" + return "customers/{customer_id}/paidOrganicSearchTermViews/{campaign_id}~{ad_group_id}~{base64_search_term}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + base64_search_term=base64_search_term, + ) + + @staticmethod + def parse_paid_organic_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a paid_organic_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paidOrganicSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def parental_status_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified parental_status_view string.""" + return "customers/{customer_id}/parentalStatusViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_parental_status_view_path(path: str) -> Dict[str, str]: + """Parses a parental_status_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/parentalStatusViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def per_store_view_path(customer_id: str, place_id: str,) -> str: + """Returns a fully-qualified per_store_view string.""" + return "customers/{customer_id}/perStoreViews/{place_id}".format( + customer_id=customer_id, place_id=place_id, + ) + + @staticmethod + def parse_per_store_view_path(path: str) -> Dict[str, str]: + """Parses a per_store_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/perStoreViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_bidding_category_constant_path( + country_code: str, level: str, id: str, + ) -> str: + """Returns a fully-qualified product_bidding_category_constant string.""" + return "productBiddingCategoryConstants/{country_code}~{level}~{id}".format( + country_code=country_code, level=level, id=id, + ) + + @staticmethod + def parse_product_bidding_category_constant_path( + path: str, + ) -> Dict[str, str]: + """Parses a product_bidding_category_constant path into its component segments.""" + m = re.match( + r"^productBiddingCategoryConstants/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_group_view_path( + customer_id: str, adgroup_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified product_group_view string.""" + return "customers/{customer_id}/productGroupViews/{adgroup_id}~{criterion_id}".format( + customer_id=customer_id, + adgroup_id=adgroup_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_product_group_view_path(path: str) -> Dict[str, str]: + """Parses a product_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_path(customer_id: str, recommendation_id: str,) -> str: + """Returns a fully-qualified recommendation string.""" + return "customers/{customer_id}/recommendations/{recommendation_id}".format( + customer_id=customer_id, recommendation_id=recommendation_id, + ) + + @staticmethod + def parse_recommendation_path(path: str) -> Dict[str, str]: + """Parses a recommendation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def remarketing_action_path( + customer_id: str, remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def search_term_view_path( + customer_id: str, campaign_id: str, ad_group_id: str, query: str, + ) -> str: + """Returns a fully-qualified search_term_view string.""" + return "customers/{customer_id}/searchTermViews/{campaign_id}~{ad_group_id}~{query}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + query=query, + ) + + @staticmethod + def parse_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/searchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_criterion_path( + customer_id: str, shared_set_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path(customer_id: str, shared_set_id: str,) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shopping_performance_view_path(customer_id: str,) -> str: + """Returns a fully-qualified shopping_performance_view string.""" + return "customers/{customer_id}/shoppingPerformanceView".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_shopping_performance_view_path(path: str) -> Dict[str, str]: + """Parses a shopping_performance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/shoppingPerformanceView$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_search_term_view_path( + customer_id: str, campaign_id: str, query: str, + ) -> str: + """Returns a fully-qualified smart_campaign_search_term_view string.""" + return "customers/{customer_id}/smartCampaignSearchTermViews/{campaign_id}~{query}".format( + customer_id=customer_id, campaign_id=campaign_id, query=query, + ) + + @staticmethod + def parse_smart_campaign_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSearchTermViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def third_party_app_analytics_link_path( + customer_id: str, customer_link_id: str, + ) -> str: + """Returns a fully-qualified third_party_app_analytics_link string.""" + return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( + customer_id=customer_id, customer_link_id=customer_link_id, + ) + + @staticmethod + def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: + """Parses a third_party_app_analytics_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_constant_path(topic_id: str,) -> str: + """Returns a fully-qualified topic_constant string.""" + return "topicConstants/{topic_id}".format(topic_id=topic_id,) + + @staticmethod + def parse_topic_constant_path(path: str) -> Dict[str, str]: + """Parses a topic_constant path into its component segments.""" + m = re.match(r"^topicConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def topic_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified topic_view string.""" + return "customers/{customer_id}/topicViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_topic_view_path(path: str) -> Dict[str, str]: + """Parses a topic_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/topicViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path(customer_id: str, user_interest_id: str,) -> str: + """Returns a fully-qualified user_interest string.""" + return "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, user_interest_id=user_interest_id, + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path(customer_id: str, user_list_id: str,) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_location_view_path( + customer_id: str, country_criterion_id: str, is_targeting_location: str, + ) -> str: + """Returns a fully-qualified user_location_view string.""" + return "customers/{customer_id}/userLocationViews/{country_criterion_id}~{is_targeting_location}".format( + customer_id=customer_id, + country_criterion_id=country_criterion_id, + is_targeting_location=is_targeting_location, + ) + + @staticmethod + def parse_user_location_view_path(path: str) -> Dict[str, str]: + """Parses a user_location_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLocationViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def video_path(customer_id: str, video_id: str,) -> str: + """Returns a fully-qualified video string.""" + return "customers/{customer_id}/videos/{video_id}".format( + customer_id=customer_id, video_id=video_id, + ) + + @staticmethod + def parse_video_path(path: str) -> Dict[str, str]: + """Parses a video path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/videos/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def webpage_view_path( + customer_id: str, ad_group_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified webpage_view string.""" + return "customers/{customer_id}/webpageViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_webpage_view_path(path: str) -> Dict[str, str]: + """Parses a webpage_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/webpageViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, GoogleAdsServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, GoogleAdsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, GoogleAdsServiceTransport): + # transport is a GoogleAdsServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def search( + self, + request: Union[google_ads_service.SearchGoogleAdsRequest, dict] = None, + *, + customer_id: str = None, + query: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchPager: + r"""Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.SearchGoogleAdsRequest, dict]): + The request object. Request message for + [GoogleAdsService.Search][google.ads.googleads.v12.services.GoogleAdsService.Search]. + customer_id (str): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.google_ads_service.pagers.SearchPager: + Response message for + [GoogleAdsService.Search][google.ads.googleads.v12.services.GoogleAdsService.Search]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, query]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a google_ads_service.SearchGoogleAdsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, google_ads_service.SearchGoogleAdsRequest): + request = google_ads_service.SearchGoogleAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def search_stream( + self, + request: Union[ + google_ads_service.SearchGoogleAdsStreamRequest, dict + ] = None, + *, + customer_id: str = None, + query: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> Iterable[google_ads_service.SearchGoogleAdsStreamResponse]: + r"""Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.SearchGoogleAdsStreamRequest, dict]): + The request object. Request message for + [GoogleAdsService.SearchStream][google.ads.googleads.v12.services.GoogleAdsService.SearchStream]. + customer_id (str): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + Iterable[google.ads.googleads.v12.services.types.SearchGoogleAdsStreamResponse]: + Response message for + [GoogleAdsService.SearchStream][google.ads.googleads.v12.services.GoogleAdsService.SearchStream]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, query]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a google_ads_service.SearchGoogleAdsStreamRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, google_ads_service.SearchGoogleAdsStreamRequest + ): + request = google_ads_service.SearchGoogleAdsStreamRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search_stream] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate( + self, + request: Union[google_ads_service.MutateGoogleAdsRequest, dict] = None, + *, + customer_id: str = None, + mutate_operations: Sequence[google_ads_service.MutateOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> google_ads_service.MutateGoogleAdsResponse: + r"""Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name + can be reused. For example, the previous + CampaignBudget+Campaign example would fail if the mutate + order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateGoogleAdsRequest, dict]): + The request object. Request message for + [GoogleAdsService.Mutate][google.ads.googleads.v12.services.GoogleAdsService.Mutate]. + customer_id (str): + Required. The ID of the customer + whose resources are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (Sequence[google.ads.googleads.v12.services.types.MutateOperation]): + Required. The list of operations to + perform on individual resources. + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateGoogleAdsResponse: + Response message for + [GoogleAdsService.Mutate][google.ads.googleads.v12.services.GoogleAdsService.Mutate]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, mutate_operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a google_ads_service.MutateGoogleAdsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, google_ads_service.MutateGoogleAdsRequest): + request = google_ads_service.MutateGoogleAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if mutate_operations is not None: + request.mutate_operations = mutate_operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("GoogleAdsServiceClient",) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/pagers.py b/google/ads/googleads/v12/services/services/google_ads_service/pagers.py new file mode 100644 index 000000000..b0fa49570 --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/pagers.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.services.types import google_ads_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.SearchGoogleAdsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.SearchGoogleAdsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., google_ads_service.SearchGoogleAdsResponse], + request: google_ads_service.SearchGoogleAdsRequest, + response: google_ads_service.SearchGoogleAdsResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.SearchGoogleAdsRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.SearchGoogleAdsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = google_ads_service.SearchGoogleAdsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[google_ads_service.SearchGoogleAdsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__(self) -> Iterator[google_ads_service.GoogleAdsRow]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/transports/__init__.py b/google/ads/googleads/v12/services/services/google_ads_service/transports/__init__.py new file mode 100644 index 000000000..af70cd65c --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 GoogleAdsServiceTransport +from .grpc import GoogleAdsServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[GoogleAdsServiceTransport]] +_transport_registry["grpc"] = GoogleAdsServiceGrpcTransport + +__all__ = ( + "GoogleAdsServiceTransport", + "GoogleAdsServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/transports/base.py b/google/ads/googleads/v12/services/services/google_ads_service/transports/base.py new file mode 100644 index 000000000..0f472ae19 --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/transports/base.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import google_ads_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class GoogleAdsServiceTransport(abc.ABC): + """Abstract transport class for GoogleAdsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.search: gapic_v1.method.wrap_method( + self.search, default_timeout=None, client_info=client_info, + ), + self.search_stream: gapic_v1.method.wrap_method( + self.search_stream, + default_timeout=None, + client_info=client_info, + ), + self.mutate: gapic_v1.method.wrap_method( + self.mutate, default_timeout=None, client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def search( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsRequest], + Union[ + google_ads_service.SearchGoogleAdsResponse, + Awaitable[google_ads_service.SearchGoogleAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def search_stream( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsStreamRequest], + Union[ + google_ads_service.SearchGoogleAdsStreamResponse, + Awaitable[google_ads_service.SearchGoogleAdsStreamResponse], + ], + ]: + raise NotImplementedError() + + @property + def mutate( + self, + ) -> Callable[ + [google_ads_service.MutateGoogleAdsRequest], + Union[ + google_ads_service.MutateGoogleAdsResponse, + Awaitable[google_ads_service.MutateGoogleAdsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("GoogleAdsServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/google_ads_service/transports/grpc.py b/google/ads/googleads/v12/services/services/google_ads_service/transports/grpc.py new file mode 100644 index 000000000..a115263ec --- /dev/null +++ b/google/ads/googleads/v12/services/services/google_ads_service/transports/grpc.py @@ -0,0 +1,424 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import google_ads_service +from .base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO + + +class GoogleAdsServiceGrpcTransport(GoogleAdsServiceTransport): + """gRPC backend transport for GoogleAdsService. + + Service to fetch data and metrics across resources. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def search( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsRequest], + google_ads_service.SearchGoogleAdsResponse, + ]: + r"""Return a callable for the search method over gRPC. + + Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsRequest], + ~.SearchGoogleAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search" not in self._stubs: + self._stubs["search"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.GoogleAdsService/Search", + request_serializer=google_ads_service.SearchGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsResponse.deserialize, + ) + return self._stubs["search"] + + @property + def search_stream( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsStreamRequest], + google_ads_service.SearchGoogleAdsStreamResponse, + ]: + r"""Return a callable for the search stream method over gRPC. + + Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsStreamRequest], + ~.SearchGoogleAdsStreamResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_stream" not in self._stubs: + self._stubs["search_stream"] = self.grpc_channel.unary_stream( + "/google.ads.googleads.v12.services.GoogleAdsService/SearchStream", + request_serializer=google_ads_service.SearchGoogleAdsStreamRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsStreamResponse.deserialize, + ) + return self._stubs["search_stream"] + + @property + def mutate( + self, + ) -> Callable[ + [google_ads_service.MutateGoogleAdsRequest], + google_ads_service.MutateGoogleAdsResponse, + ]: + r"""Return a callable for the mutate method over gRPC. + + Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name + can be reused. For example, the previous + CampaignBudget+Campaign example would fail if the mutate + order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateGoogleAdsRequest], + ~.MutateGoogleAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate" not in self._stubs: + self._stubs["mutate"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.GoogleAdsService/Mutate", + request_serializer=google_ads_service.MutateGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.MutateGoogleAdsResponse.deserialize, + ) + return self._stubs["mutate"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("GoogleAdsServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/invoice_service/__init__.py b/google/ads/googleads/v12/services/services/invoice_service/__init__.py new file mode 100644 index 000000000..16c03e654 --- /dev/null +++ b/google/ads/googleads/v12/services/services/invoice_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 InvoiceServiceClient + +__all__ = ("InvoiceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/invoice_service/client.py b/google/ads/googleads/v12/services/services/invoice_service/client.py new file mode 100644 index 000000000..a24c9ce8f --- /dev/null +++ b/google/ads/googleads/v12/services/services/invoice_service/client.py @@ -0,0 +1,509 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.enums.types import month_of_year +from google.ads.googleads.v12.services.types import invoice_service +from .transports.base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import InvoiceServiceGrpcTransport + + +class InvoiceServiceClientMeta(type): + """Metaclass for the InvoiceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[InvoiceServiceTransport]] + _transport_registry["grpc"] = InvoiceServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[InvoiceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class InvoiceServiceClient(metaclass=InvoiceServiceClientMeta): + """A service to fetch invoices issued for a billing setup during + a given month. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> InvoiceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + InvoiceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def invoice_path(customer_id: str, invoice_id: str,) -> str: + """Returns a fully-qualified invoice string.""" + return "customers/{customer_id}/invoices/{invoice_id}".format( + customer_id=customer_id, invoice_id=invoice_id, + ) + + @staticmethod + def parse_invoice_path(path: str) -> Dict[str, str]: + """Parses a invoice path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/invoices/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, InvoiceServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the invoice service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, InvoiceServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, InvoiceServiceTransport): + # transport is a InvoiceServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def list_invoices( + self, + request: Union[invoice_service.ListInvoicesRequest, dict] = None, + *, + customer_id: str = None, + billing_setup: str = None, + issue_year: str = None, + issue_month: month_of_year.MonthOfYearEnum.MonthOfYear = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> invoice_service.ListInvoicesResponse: + r"""Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListInvoicesRequest, dict]): + The request object. Request message for fetching the + invoices of a given billing setup that were issued + during a given month. + customer_id (str): + Required. The ID of the customer to + fetch invoices for. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + billing_setup (str): + Required. The billing setup resource name of the + requested invoices. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + + This corresponds to the ``billing_setup`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_year (str): + Required. The issue year to retrieve + invoices, in yyyy format. Only invoices + issued in 2019 or later can be + retrieved. + + This corresponds to the ``issue_year`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_month (google.ads.googleads.v12.enums.types.MonthOfYearEnum.MonthOfYear): + Required. The issue month to retrieve + invoices. + + This corresponds to the ``issue_month`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListInvoicesResponse: + Response message for + [InvoiceService.ListInvoices][google.ads.googleads.v12.services.InvoiceService.ListInvoices]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [customer_id, billing_setup, issue_year, issue_month] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a invoice_service.ListInvoicesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, invoice_service.ListInvoicesRequest): + request = invoice_service.ListInvoicesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if billing_setup is not None: + request.billing_setup = billing_setup + if issue_year is not None: + request.issue_year = issue_year + if issue_month is not None: + request.issue_month = issue_month + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_invoices] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("InvoiceServiceClient",) diff --git a/google/ads/googleads/v12/services/services/invoice_service/transports/__init__.py b/google/ads/googleads/v12/services/services/invoice_service/transports/__init__.py new file mode 100644 index 000000000..6f1e97b91 --- /dev/null +++ b/google/ads/googleads/v12/services/services/invoice_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 InvoiceServiceTransport +from .grpc import InvoiceServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[InvoiceServiceTransport]] +_transport_registry["grpc"] = InvoiceServiceGrpcTransport + +__all__ = ( + "InvoiceServiceTransport", + "InvoiceServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/invoice_service/transports/base.py b/google/ads/googleads/v12/services/services/invoice_service/transports/base.py new file mode 100644 index 000000000..24d05f600 --- /dev/null +++ b/google/ads/googleads/v12/services/services/invoice_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import invoice_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class InvoiceServiceTransport(abc.ABC): + """Abstract transport class for InvoiceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_invoices: gapic_v1.method.wrap_method( + self.list_invoices, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_invoices( + self, + ) -> Callable[ + [invoice_service.ListInvoicesRequest], + Union[ + invoice_service.ListInvoicesResponse, + Awaitable[invoice_service.ListInvoicesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("InvoiceServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/invoice_service/transports/grpc.py b/google/ads/googleads/v12/services/services/invoice_service/transports/grpc.py new file mode 100644 index 000000000..80d27821b --- /dev/null +++ b/google/ads/googleads/v12/services/services/invoice_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import invoice_service +from .base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO + + +class InvoiceServiceGrpcTransport(InvoiceServiceTransport): + """gRPC backend transport for InvoiceService. + + A service to fetch invoices issued for a billing setup during + a given month. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def list_invoices( + self, + ) -> Callable[ + [invoice_service.ListInvoicesRequest], + invoice_service.ListInvoicesResponse, + ]: + r"""Return a callable for the list invoices method over gRPC. + + Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInvoicesRequest], + ~.ListInvoicesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_invoices" not in self._stubs: + self._stubs["list_invoices"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.InvoiceService/ListInvoices", + request_serializer=invoice_service.ListInvoicesRequest.serialize, + response_deserializer=invoice_service.ListInvoicesResponse.deserialize, + ) + return self._stubs["list_invoices"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("InvoiceServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/__init__.py new file mode 100644 index 000000000..7e4d8f572 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanAdGroupKeywordServiceClient + +__all__ = ("KeywordPlanAdGroupKeywordServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/client.py new file mode 100644 index 000000000..aaa7f05a1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/client.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanAdGroupKeywordServiceGrpcTransport + + +class KeywordPlanAdGroupKeywordServiceClientMeta(type): + """Metaclass for the KeywordPlanAdGroupKeywordService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanAdGroupKeywordServiceTransport]] + _transport_registry["grpc"] = KeywordPlanAdGroupKeywordServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanAdGroupKeywordServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanAdGroupKeywordServiceClient( + metaclass=KeywordPlanAdGroupKeywordServiceClientMeta +): + """Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanAdGroupKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupKeywordServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, KeywordPlanAdGroupKeywordServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group keyword service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanAdGroupKeywordServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanAdGroupKeywordServiceTransport): + # transport is a KeywordPlanAdGroupKeywordServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_keyword_plan_ad_group_keywords( + self, + request: Union[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse: + r"""Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupKeywordsRequest, dict]): + The request object. Request message for + [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v12.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan ad group keywords are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanAdGroupKeywordOperation]): + Required. The list of operations to + perform on individual Keyword Plan ad + group keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupKeywordsResponse: + Response message for a Keyword Plan + ad group keyword mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + ): + request = keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_ad_group_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanAdGroupKeywordServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py new file mode 100644 index 000000000..0a16dce33 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanAdGroupKeywordServiceTransport +from .grpc import KeywordPlanAdGroupKeywordServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanAdGroupKeywordServiceTransport]] +_transport_registry["grpc"] = KeywordPlanAdGroupKeywordServiceGrpcTransport + +__all__ = ( + "KeywordPlanAdGroupKeywordServiceTransport", + "KeywordPlanAdGroupKeywordServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/base.py new file mode 100644 index 000000000..8e4f4e053 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_keyword_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanAdGroupKeywordServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanAdGroupKeywordService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_ad_group_keywords: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_ad_group_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_ad_group_keywords( + self, + ) -> Callable[ + [ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest + ], + Union[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, + Awaitable[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanAdGroupKeywordServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py new file mode 100644 index 000000000..289ccc634 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from .base import KeywordPlanAdGroupKeywordServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordPlanAdGroupKeywordServiceGrpcTransport( + KeywordPlanAdGroupKeywordServiceTransport +): + """gRPC backend transport for KeywordPlanAdGroupKeywordService. + + Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_group_keywords( + self, + ) -> Callable[ + [ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest + ], + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, + ]: + r"""Return a callable for the mutate keyword plan ad group + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupKeywordsRequest], + ~.MutateKeywordPlanAdGroupKeywordsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_group_keywords" not in self._stubs: + self._stubs[ + "mutate_keyword_plan_ad_group_keywords" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanAdGroupKeywordService/MutateKeywordPlanAdGroupKeywords", + request_serializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest.serialize, + response_deserializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse.deserialize, + ) + return self._stubs["mutate_keyword_plan_ad_group_keywords"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanAdGroupKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/__init__.py new file mode 100644 index 000000000..29af45a71 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanAdGroupServiceClient + +__all__ = ("KeywordPlanAdGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/client.py new file mode 100644 index 000000000..e4907bd8b --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/client.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanAdGroupServiceGrpcTransport + + +class KeywordPlanAdGroupServiceClientMeta(type): + """Metaclass for the KeywordPlanAdGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanAdGroupServiceTransport]] + _transport_registry["grpc"] = KeywordPlanAdGroupServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanAdGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanAdGroupServiceClient( + metaclass=KeywordPlanAdGroupServiceClientMeta +): + """Service to manage Keyword Plan ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanAdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, KeywordPlanAdGroupServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanAdGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanAdGroupServiceTransport): + # transport is a KeywordPlanAdGroupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_keyword_plan_ad_groups( + self, + request: Union[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + keyword_plan_ad_group_service.KeywordPlanAdGroupOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse: + r"""Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupsRequest, dict]): + The request object. Request message for + [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v12.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan ad groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanAdGroupOperation]): + Required. The list of operations to + perform on individual Keyword Plan ad + groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupsResponse: + Response message for a Keyword Plan + ad group mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, + ): + request = keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_ad_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanAdGroupServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/__init__.py new file mode 100644 index 000000000..5e54e7580 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanAdGroupServiceTransport +from .grpc import KeywordPlanAdGroupServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanAdGroupServiceTransport]] +_transport_registry["grpc"] = KeywordPlanAdGroupServiceGrpcTransport + +__all__ = ( + "KeywordPlanAdGroupServiceTransport", + "KeywordPlanAdGroupServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/base.py new file mode 100644 index 000000000..4e1399ecd --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanAdGroupServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanAdGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_ad_groups: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_ad_groups( + self, + ) -> Callable[ + [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], + Union[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, + Awaitable[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanAdGroupServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/grpc.py new file mode 100644 index 000000000..55d3ce3a8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_ad_group_service/transports/grpc.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_service, +) +from .base import KeywordPlanAdGroupServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordPlanAdGroupServiceGrpcTransport( + KeywordPlanAdGroupServiceTransport +): + """gRPC backend transport for KeywordPlanAdGroupService. + + Service to manage Keyword Plan ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_groups( + self, + ) -> Callable[ + [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, + ]: + r"""Return a callable for the mutate keyword plan ad groups method over gRPC. + + Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupsRequest], + ~.MutateKeywordPlanAdGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_groups" not in self._stubs: + self._stubs[ + "mutate_keyword_plan_ad_groups" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanAdGroupService/MutateKeywordPlanAdGroups", + request_serializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest.serialize, + response_deserializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse.deserialize, + ) + return self._stubs["mutate_keyword_plan_ad_groups"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanAdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/__init__.py new file mode 100644 index 000000000..ae37d0652 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanCampaignKeywordServiceClient + +__all__ = ("KeywordPlanCampaignKeywordServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/client.py new file mode 100644 index 000000000..d151c7589 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/client.py @@ -0,0 +1,532 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanCampaignKeywordServiceGrpcTransport + + +class KeywordPlanCampaignKeywordServiceClientMeta(type): + """Metaclass for the KeywordPlanCampaignKeywordService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanCampaignKeywordServiceTransport]] + _transport_registry["grpc"] = KeywordPlanCampaignKeywordServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanCampaignKeywordServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanCampaignKeywordServiceClient( + metaclass=KeywordPlanCampaignKeywordServiceClientMeta +): + """Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanCampaignKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignKeywordServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, KeywordPlanCampaignKeywordServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign keyword service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanCampaignKeywordServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanCampaignKeywordServiceTransport): + # transport is a KeywordPlanCampaignKeywordServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_keyword_plan_campaign_keywords( + self, + request: Union[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse: + r"""Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignKeywordsRequest, dict]): + The request object. Request message for + [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v12.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. + customer_id (str): + Required. The ID of the customer + whose campaign keywords are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignKeywordOperation]): + Required. The list of operations to + perform on individual Keyword Plan + campaign keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignKeywordsResponse: + Response message for a Keyword Plan + campaign keyword mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + ): + request = keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_campaign_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanCampaignKeywordServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py new file mode 100644 index 000000000..773293703 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanCampaignKeywordServiceTransport +from .grpc import KeywordPlanCampaignKeywordServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanCampaignKeywordServiceTransport]] +_transport_registry["grpc"] = KeywordPlanCampaignKeywordServiceGrpcTransport + +__all__ = ( + "KeywordPlanCampaignKeywordServiceTransport", + "KeywordPlanCampaignKeywordServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/base.py new file mode 100644 index 000000000..84fe112e3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_keyword_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanCampaignKeywordServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanCampaignKeywordService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_campaign_keywords: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_campaign_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_campaign_keywords( + self, + ) -> Callable[ + [ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest + ], + Union[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, + Awaitable[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanCampaignKeywordServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py new file mode 100644 index 000000000..148d05318 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_keyword_service, +) +from .base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class KeywordPlanCampaignKeywordServiceGrpcTransport( + KeywordPlanCampaignKeywordServiceTransport +): + """gRPC backend transport for KeywordPlanCampaignKeywordService. + + Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_keyword_plan_campaign_keywords( + self, + ) -> Callable[ + [ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest + ], + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, + ]: + r"""Return a callable for the mutate keyword plan campaign + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignKeywordsRequest], + ~.MutateKeywordPlanCampaignKeywordsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaign_keywords" not in self._stubs: + self._stubs[ + "mutate_keyword_plan_campaign_keywords" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanCampaignKeywordService/MutateKeywordPlanCampaignKeywords", + request_serializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest.serialize, + response_deserializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse.deserialize, + ) + return self._stubs["mutate_keyword_plan_campaign_keywords"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanCampaignKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/__init__.py new file mode 100644 index 000000000..d6514881d --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanCampaignServiceClient + +__all__ = ("KeywordPlanCampaignServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/client.py new file mode 100644 index 000000000..d9d307fcd --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/client.py @@ -0,0 +1,549 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanCampaignServiceGrpcTransport + + +class KeywordPlanCampaignServiceClientMeta(type): + """Metaclass for the KeywordPlanCampaignService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanCampaignServiceTransport]] + _transport_registry["grpc"] = KeywordPlanCampaignServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanCampaignServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanCampaignServiceClient( + metaclass=KeywordPlanCampaignServiceClientMeta +): + """Service to manage Keyword Plan campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanCampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def geo_target_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path(customer_id: str, keyword_plan_id: str,) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path(criterion_id: str,) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, KeywordPlanCampaignServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanCampaignServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanCampaignServiceTransport): + # transport is a KeywordPlanCampaignServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_keyword_plan_campaigns( + self, + request: Union[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + keyword_plan_campaign_service.KeywordPlanCampaignOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse: + r"""Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignsRequest, dict]): + The request object. Request message for + [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v12.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan campaigns are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignOperation]): + Required. The list of operations to + perform on individual Keyword Plan + campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignsResponse: + Response message for a Keyword Plan + campaign mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + ): + request = keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_campaigns + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanCampaignServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/__init__.py new file mode 100644 index 000000000..7a330600e --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanCampaignServiceTransport +from .grpc import KeywordPlanCampaignServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanCampaignServiceTransport]] +_transport_registry["grpc"] = KeywordPlanCampaignServiceGrpcTransport + +__all__ = ( + "KeywordPlanCampaignServiceTransport", + "KeywordPlanCampaignServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/base.py new file mode 100644 index 000000000..0b3a94d9f --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanCampaignServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanCampaignService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_campaigns: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_campaigns, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_campaigns( + self, + ) -> Callable[ + [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], + Union[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, + Awaitable[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanCampaignServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/grpc.py new file mode 100644 index 000000000..bd5804213 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_campaign_service/transports/grpc.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_service, +) +from .base import KeywordPlanCampaignServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordPlanCampaignServiceGrpcTransport( + KeywordPlanCampaignServiceTransport +): + """gRPC backend transport for KeywordPlanCampaignService. + + Service to manage Keyword Plan campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_keyword_plan_campaigns( + self, + ) -> Callable[ + [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, + ]: + r"""Return a callable for the mutate keyword plan campaigns method over gRPC. + + Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignsRequest], + ~.MutateKeywordPlanCampaignsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaigns" not in self._stubs: + self._stubs[ + "mutate_keyword_plan_campaigns" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanCampaignService/MutateKeywordPlanCampaigns", + request_serializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest.serialize, + response_deserializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse.deserialize, + ) + return self._stubs["mutate_keyword_plan_campaigns"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanCampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/__init__.py new file mode 100644 index 000000000..22dc0368d --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanIdeaServiceClient + +__all__ = ("KeywordPlanIdeaServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/client.py new file mode 100644 index 000000000..886a93c48 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/client.py @@ -0,0 +1,592 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.services.keyword_plan_idea_service import ( + pagers, +) +from google.ads.googleads.v12.services.types import keyword_plan_idea_service +from .transports.base import ( + KeywordPlanIdeaServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanIdeaServiceGrpcTransport + + +class KeywordPlanIdeaServiceClientMeta(type): + """Metaclass for the KeywordPlanIdeaService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanIdeaServiceTransport]] + _transport_registry["grpc"] = KeywordPlanIdeaServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanIdeaServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanIdeaServiceClient(metaclass=KeywordPlanIdeaServiceClientMeta): + """Service to generate keyword ideas.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanIdeaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanIdeaServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, KeywordPlanIdeaServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan idea service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanIdeaServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanIdeaServiceTransport): + # transport is a KeywordPlanIdeaServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def generate_keyword_ideas( + self, + request: Union[ + keyword_plan_idea_service.GenerateKeywordIdeasRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.GenerateKeywordIdeasPager: + r"""Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateKeywordIdeasRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.services.keyword_plan_idea_service.pagers.GenerateKeywordIdeasPager: + Response message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_idea_service.GenerateKeywordIdeasRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_idea_service.GenerateKeywordIdeasRequest + ): + request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_keyword_ideas + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.GenerateKeywordIdeasPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_keyword_historical_metrics( + self, + request: Union[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + dict, + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse: + r"""Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateKeywordHistoricalMetricsRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateKeywordHistoricalMetricsResponse: + Response message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + ): + request = keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_keyword_historical_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_ad_group_themes( + self, + request: Union[ + keyword_plan_idea_service.GenerateAdGroupThemesRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_idea_service.GenerateAdGroupThemesResponse: + r"""Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateAdGroupThemesRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateAdGroupThemesResponse: + Response message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_idea_service.GenerateAdGroupThemesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_idea_service.GenerateAdGroupThemesRequest + ): + request = keyword_plan_idea_service.GenerateAdGroupThemesRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_ad_group_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanIdeaServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/pagers.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/pagers.py new file mode 100644 index 000000000..5b2b24660 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/pagers.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Iterable, Iterator, Sequence, Tuple + +from google.ads.googleads.v12.services.types import keyword_plan_idea_service + + +class GenerateKeywordIdeasPager: + """A pager for iterating through ``generate_keyword_ideas`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v12.services.types.GenerateKeywordIdeaResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``GenerateKeywordIdeas`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v12.services.types.GenerateKeywordIdeaResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., keyword_plan_idea_service.GenerateKeywordIdeaResponse + ], + request: keyword_plan_idea_service.GenerateKeywordIdeasRequest, + response: keyword_plan_idea_service.GenerateKeywordIdeaResponse, + metadata: Sequence[Tuple[str, str]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`google.ads.googleads.v12.services.types.GenerateKeywordIdeasRequest`): + The initial request object. + response (:class:`google.ads.googleads.v12.services.types.GenerateKeywordIdeaResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterable[keyword_plan_idea_service.GenerateKeywordIdeaResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, metadata=self._metadata + ) + yield self._response + + def __iter__( + self, + ) -> Iterator[keyword_plan_idea_service.GenerateKeywordIdeaResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/__init__.py new file mode 100644 index 000000000..7bd34e5ab --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanIdeaServiceTransport +from .grpc import KeywordPlanIdeaServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanIdeaServiceTransport]] +_transport_registry["grpc"] = KeywordPlanIdeaServiceGrpcTransport + +__all__ = ( + "KeywordPlanIdeaServiceTransport", + "KeywordPlanIdeaServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/base.py new file mode 100644 index 000000000..b851987b3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import keyword_plan_idea_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanIdeaServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanIdeaService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_keyword_ideas: gapic_v1.method.wrap_method( + self.generate_keyword_ideas, + default_timeout=None, + client_info=client_info, + ), + self.generate_keyword_historical_metrics: gapic_v1.method.wrap_method( + self.generate_keyword_historical_metrics, + default_timeout=None, + client_info=client_info, + ), + self.generate_ad_group_themes: gapic_v1.method.wrap_method( + self.generate_ad_group_themes, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_keyword_ideas( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordIdeasRequest], + Union[ + keyword_plan_idea_service.GenerateKeywordIdeaResponse, + Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_keyword_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], + Union[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, + Awaitable[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_ad_group_themes( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateAdGroupThemesRequest], + Union[ + keyword_plan_idea_service.GenerateAdGroupThemesResponse, + Awaitable[keyword_plan_idea_service.GenerateAdGroupThemesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanIdeaServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/grpc.py new file mode 100644 index 000000000..607b8a0d7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_idea_service/transports/grpc.py @@ -0,0 +1,350 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import keyword_plan_idea_service +from .base import KeywordPlanIdeaServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordPlanIdeaServiceGrpcTransport(KeywordPlanIdeaServiceTransport): + """gRPC backend transport for KeywordPlanIdeaService. + + Service to generate keyword ideas. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def generate_keyword_ideas( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordIdeasRequest], + keyword_plan_idea_service.GenerateKeywordIdeaResponse, + ]: + r"""Return a callable for the generate keyword ideas method over gRPC. + + Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordIdeasRequest], + ~.GenerateKeywordIdeaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_ideas" not in self._stubs: + self._stubs[ + "generate_keyword_ideas" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanIdeaService/GenerateKeywordIdeas", + request_serializer=keyword_plan_idea_service.GenerateKeywordIdeasRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordIdeaResponse.deserialize, + ) + return self._stubs["generate_keyword_ideas"] + + @property + def generate_keyword_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, + ]: + r"""Return a callable for the generate keyword historical + metrics method over gRPC. + + Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordHistoricalMetricsRequest], + ~.GenerateKeywordHistoricalMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_historical_metrics" not in self._stubs: + self._stubs[ + "generate_keyword_historical_metrics" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanIdeaService/GenerateKeywordHistoricalMetrics", + request_serializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse.deserialize, + ) + return self._stubs["generate_keyword_historical_metrics"] + + @property + def generate_ad_group_themes( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateAdGroupThemesRequest], + keyword_plan_idea_service.GenerateAdGroupThemesResponse, + ]: + r"""Return a callable for the generate ad group themes method over gRPC. + + Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateAdGroupThemesRequest], + ~.GenerateAdGroupThemesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_ad_group_themes" not in self._stubs: + self._stubs[ + "generate_ad_group_themes" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanIdeaService/GenerateAdGroupThemes", + request_serializer=keyword_plan_idea_service.GenerateAdGroupThemesRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateAdGroupThemesResponse.deserialize, + ) + return self._stubs["generate_ad_group_themes"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanIdeaServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_service/__init__.py new file mode 100644 index 000000000..cecf578a5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordPlanServiceClient + +__all__ = ("KeywordPlanServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_service/client.py b/google/ads/googleads/v12/services/services/keyword_plan_service/client.py new file mode 100644 index 000000000..6404d6753 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_service/client.py @@ -0,0 +1,850 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import keyword_plan_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import KeywordPlanServiceGrpcTransport + + +class KeywordPlanServiceClientMeta(type): + """Metaclass for the KeywordPlanService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanServiceTransport]] + _transport_registry["grpc"] = KeywordPlanServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordPlanServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanServiceClient(metaclass=KeywordPlanServiceClientMeta): + """Service to manage keyword plans.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def keyword_plan_path(customer_id: str, keyword_plan_id: str,) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, KeywordPlanServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordPlanServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordPlanServiceTransport): + # transport is a KeywordPlanServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_keyword_plans( + self, + request: Union[ + keyword_plan_service.MutateKeywordPlansRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[keyword_plan_service.KeywordPlanOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_service.MutateKeywordPlansResponse: + r"""Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateKeywordPlansRequest, dict]): + The request object. Request message for + [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v12.services.KeywordPlanService.MutateKeywordPlans]. + customer_id (str): + Required. The ID of the customer + whose keyword plans are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanOperation]): + Required. The list of operations to + perform on individual keyword plans. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateKeywordPlansResponse: + Response message for a keyword plan + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_service.MutateKeywordPlansRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_service.MutateKeywordPlansRequest + ): + request = keyword_plan_service.MutateKeywordPlansRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plans + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_forecast_curve( + self, + request: Union[ + keyword_plan_service.GenerateForecastCurveRequest, dict + ] = None, + *, + keyword_plan: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_service.GenerateForecastCurveResponse: + r"""Returns the requested Keyword Plan forecast curve. Only the + bidding strategy is considered for generating forecast curve. + The bidding strategy value specified in the plan is ignored. + + To generate a forecast at a value specified in the plan, use + KeywordPlanService.GenerateForecastMetrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateForecastCurveRequest, dict]): + The request object. Request message for + [KeywordPlanService.GenerateForecastCurve][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastCurve]. + keyword_plan (str): + Required. The resource name of the + keyword plan to be forecasted. + + This corresponds to the ``keyword_plan`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateForecastCurveResponse: + Response message for + [KeywordPlanService.GenerateForecastCurve][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastCurve]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([keyword_plan]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_service.GenerateForecastCurveRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_service.GenerateForecastCurveRequest + ): + request = keyword_plan_service.GenerateForecastCurveRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if keyword_plan is not None: + request.keyword_plan = keyword_plan + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_forecast_curve + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("keyword_plan", request.keyword_plan),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_forecast_time_series( + self, + request: Union[ + keyword_plan_service.GenerateForecastTimeSeriesRequest, dict + ] = None, + *, + keyword_plan: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_service.GenerateForecastTimeSeriesResponse: + r"""Returns a forecast in the form of a time series for the Keyword + Plan over the next 52 weeks. (1) Forecasts closer to the current + date are generally more accurate than further out. + + (2) The forecast reflects seasonal trends using current and + prior traffic patterns. The forecast period of the plan is + ignored. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateForecastTimeSeriesRequest, dict]): + The request object. Request message for + [KeywordPlanService.GenerateForecastTimeSeries][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastTimeSeries]. + keyword_plan (str): + Required. The resource name of the + keyword plan to be forecasted. + + This corresponds to the ``keyword_plan`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateForecastTimeSeriesResponse: + Response message for + [KeywordPlanService.GenerateForecastTimeSeries][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastTimeSeries]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([keyword_plan]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_service.GenerateForecastTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_service.GenerateForecastTimeSeriesRequest + ): + request = keyword_plan_service.GenerateForecastTimeSeriesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if keyword_plan is not None: + request.keyword_plan = keyword_plan + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_forecast_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("keyword_plan", request.keyword_plan),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_forecast_metrics( + self, + request: Union[ + keyword_plan_service.GenerateForecastMetricsRequest, dict + ] = None, + *, + keyword_plan: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_service.GenerateForecastMetricsResponse: + r"""Returns the requested Keyword Plan forecasts. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateForecastMetricsRequest, dict]): + The request object. Request message for + [KeywordPlanService.GenerateForecastMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastMetrics]. + keyword_plan (str): + Required. The resource name of the + keyword plan to be forecasted. + + This corresponds to the ``keyword_plan`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateForecastMetricsResponse: + Response message for + [KeywordPlanService.GenerateForecastMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastMetrics]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([keyword_plan]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_service.GenerateForecastMetricsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_service.GenerateForecastMetricsRequest + ): + request = keyword_plan_service.GenerateForecastMetricsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if keyword_plan is not None: + request.keyword_plan = keyword_plan + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_forecast_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("keyword_plan", request.keyword_plan),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_historical_metrics( + self, + request: Union[ + keyword_plan_service.GenerateHistoricalMetricsRequest, dict + ] = None, + *, + keyword_plan: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_plan_service.GenerateHistoricalMetricsResponse: + r"""Returns the requested Keyword Plan historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateHistoricalMetricsRequest, dict]): + The request object. Request message for + [KeywordPlanService.GenerateHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateHistoricalMetrics]. + keyword_plan (str): + Required. The resource name of the + keyword plan of which historical metrics + are requested. + + This corresponds to the ``keyword_plan`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateHistoricalMetricsResponse: + Response message for + [KeywordPlanService.GenerateHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateHistoricalMetrics]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([keyword_plan]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a keyword_plan_service.GenerateHistoricalMetricsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, keyword_plan_service.GenerateHistoricalMetricsRequest + ): + request = keyword_plan_service.GenerateHistoricalMetricsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if keyword_plan is not None: + request.keyword_plan = keyword_plan + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_historical_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("keyword_plan", request.keyword_plan),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordPlanServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/__init__.py new file mode 100644 index 000000000..ca5f965ee --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordPlanServiceTransport +from .grpc import KeywordPlanServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordPlanServiceTransport]] +_transport_registry["grpc"] = KeywordPlanServiceGrpcTransport + +__all__ = ( + "KeywordPlanServiceTransport", + "KeywordPlanServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/base.py new file mode 100644 index 000000000..a745bea05 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/base.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import keyword_plan_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordPlanServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plans: gapic_v1.method.wrap_method( + self.mutate_keyword_plans, + default_timeout=None, + client_info=client_info, + ), + self.generate_forecast_curve: gapic_v1.method.wrap_method( + self.generate_forecast_curve, + default_timeout=None, + client_info=client_info, + ), + self.generate_forecast_time_series: gapic_v1.method.wrap_method( + self.generate_forecast_time_series, + default_timeout=None, + client_info=client_info, + ), + self.generate_forecast_metrics: gapic_v1.method.wrap_method( + self.generate_forecast_metrics, + default_timeout=None, + client_info=client_info, + ), + self.generate_historical_metrics: gapic_v1.method.wrap_method( + self.generate_historical_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plans( + self, + ) -> Callable[ + [keyword_plan_service.MutateKeywordPlansRequest], + Union[ + keyword_plan_service.MutateKeywordPlansResponse, + Awaitable[keyword_plan_service.MutateKeywordPlansResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_forecast_curve( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastCurveRequest], + Union[ + keyword_plan_service.GenerateForecastCurveResponse, + Awaitable[keyword_plan_service.GenerateForecastCurveResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_forecast_time_series( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastTimeSeriesRequest], + Union[ + keyword_plan_service.GenerateForecastTimeSeriesResponse, + Awaitable[keyword_plan_service.GenerateForecastTimeSeriesResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_forecast_metrics( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastMetricsRequest], + Union[ + keyword_plan_service.GenerateForecastMetricsResponse, + Awaitable[keyword_plan_service.GenerateForecastMetricsResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_service.GenerateHistoricalMetricsRequest], + Union[ + keyword_plan_service.GenerateHistoricalMetricsResponse, + Awaitable[keyword_plan_service.GenerateHistoricalMetricsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordPlanServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_plan_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/grpc.py new file mode 100644 index 000000000..521ab4935 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_plan_service/transports/grpc.py @@ -0,0 +1,431 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import keyword_plan_service +from .base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordPlanServiceGrpcTransport(KeywordPlanServiceTransport): + """gRPC backend transport for KeywordPlanService. + + Service to manage keyword plans. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_keyword_plans( + self, + ) -> Callable[ + [keyword_plan_service.MutateKeywordPlansRequest], + keyword_plan_service.MutateKeywordPlansResponse, + ]: + r"""Return a callable for the mutate keyword plans method over gRPC. + + Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateKeywordPlansRequest], + ~.MutateKeywordPlansResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plans" not in self._stubs: + self._stubs["mutate_keyword_plans"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanService/MutateKeywordPlans", + request_serializer=keyword_plan_service.MutateKeywordPlansRequest.serialize, + response_deserializer=keyword_plan_service.MutateKeywordPlansResponse.deserialize, + ) + return self._stubs["mutate_keyword_plans"] + + @property + def generate_forecast_curve( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastCurveRequest], + keyword_plan_service.GenerateForecastCurveResponse, + ]: + r"""Return a callable for the generate forecast curve method over gRPC. + + Returns the requested Keyword Plan forecast curve. Only the + bidding strategy is considered for generating forecast curve. + The bidding strategy value specified in the plan is ignored. + + To generate a forecast at a value specified in the plan, use + KeywordPlanService.GenerateForecastMetrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateForecastCurveRequest], + ~.GenerateForecastCurveResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_forecast_curve" not in self._stubs: + self._stubs[ + "generate_forecast_curve" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanService/GenerateForecastCurve", + request_serializer=keyword_plan_service.GenerateForecastCurveRequest.serialize, + response_deserializer=keyword_plan_service.GenerateForecastCurveResponse.deserialize, + ) + return self._stubs["generate_forecast_curve"] + + @property + def generate_forecast_time_series( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastTimeSeriesRequest], + keyword_plan_service.GenerateForecastTimeSeriesResponse, + ]: + r"""Return a callable for the generate forecast time series method over gRPC. + + Returns a forecast in the form of a time series for the Keyword + Plan over the next 52 weeks. (1) Forecasts closer to the current + date are generally more accurate than further out. + + (2) The forecast reflects seasonal trends using current and + prior traffic patterns. The forecast period of the plan is + ignored. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateForecastTimeSeriesRequest], + ~.GenerateForecastTimeSeriesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_forecast_time_series" not in self._stubs: + self._stubs[ + "generate_forecast_time_series" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanService/GenerateForecastTimeSeries", + request_serializer=keyword_plan_service.GenerateForecastTimeSeriesRequest.serialize, + response_deserializer=keyword_plan_service.GenerateForecastTimeSeriesResponse.deserialize, + ) + return self._stubs["generate_forecast_time_series"] + + @property + def generate_forecast_metrics( + self, + ) -> Callable[ + [keyword_plan_service.GenerateForecastMetricsRequest], + keyword_plan_service.GenerateForecastMetricsResponse, + ]: + r"""Return a callable for the generate forecast metrics method over gRPC. + + Returns the requested Keyword Plan forecasts. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateForecastMetricsRequest], + ~.GenerateForecastMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_forecast_metrics" not in self._stubs: + self._stubs[ + "generate_forecast_metrics" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanService/GenerateForecastMetrics", + request_serializer=keyword_plan_service.GenerateForecastMetricsRequest.serialize, + response_deserializer=keyword_plan_service.GenerateForecastMetricsResponse.deserialize, + ) + return self._stubs["generate_forecast_metrics"] + + @property + def generate_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_service.GenerateHistoricalMetricsRequest], + keyword_plan_service.GenerateHistoricalMetricsResponse, + ]: + r"""Return a callable for the generate historical metrics method over gRPC. + + Returns the requested Keyword Plan historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `KeywordPlanError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateHistoricalMetricsRequest], + ~.GenerateHistoricalMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_historical_metrics" not in self._stubs: + self._stubs[ + "generate_historical_metrics" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordPlanService/GenerateHistoricalMetrics", + request_serializer=keyword_plan_service.GenerateHistoricalMetricsRequest.serialize, + response_deserializer=keyword_plan_service.GenerateHistoricalMetricsResponse.deserialize, + ) + return self._stubs["generate_historical_metrics"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_theme_constant_service/__init__.py b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/__init__.py new file mode 100644 index 000000000..9a60be858 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 KeywordThemeConstantServiceClient + +__all__ = ("KeywordThemeConstantServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_theme_constant_service/client.py b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/client.py new file mode 100644 index 000000000..ac7625fda --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/client.py @@ -0,0 +1,460 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_theme_constant_service, +) +from .transports.base import ( + KeywordThemeConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordThemeConstantServiceGrpcTransport + + +class KeywordThemeConstantServiceClientMeta(type): + """Metaclass for the KeywordThemeConstantService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordThemeConstantServiceTransport]] + _transport_registry["grpc"] = KeywordThemeConstantServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[KeywordThemeConstantServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordThemeConstantServiceClient( + metaclass=KeywordThemeConstantServiceClientMeta +): + """Service to fetch Smart Campaign keyword themes.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordThemeConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordThemeConstantServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, KeywordThemeConstantServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword theme constant service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, KeywordThemeConstantServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, KeywordThemeConstantServiceTransport): + # transport is a KeywordThemeConstantServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def suggest_keyword_theme_constants( + self, + request: Union[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + dict, + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse: + r"""Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.SuggestKeywordThemeConstantsRequest, dict]): + The request object. Request message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v12.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.SuggestKeywordThemeConstantsResponse: + Response message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v12.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + ): + request = keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_keyword_theme_constants + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("KeywordThemeConstantServiceClient",) diff --git a/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/__init__.py b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/__init__.py new file mode 100644 index 000000000..4779c7b4b --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 KeywordThemeConstantServiceTransport +from .grpc import KeywordThemeConstantServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[KeywordThemeConstantServiceTransport]] +_transport_registry["grpc"] = KeywordThemeConstantServiceGrpcTransport + +__all__ = ( + "KeywordThemeConstantServiceTransport", + "KeywordThemeConstantServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/base.py b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/base.py new file mode 100644 index 000000000..53636f11b --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_theme_constant_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class KeywordThemeConstantServiceTransport(abc.ABC): + """Abstract transport class for KeywordThemeConstantService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_keyword_theme_constants: gapic_v1.method.wrap_method( + self.suggest_keyword_theme_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_keyword_theme_constants( + self, + ) -> Callable[ + [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], + Union[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, + Awaitable[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("KeywordThemeConstantServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/grpc.py b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/grpc.py new file mode 100644 index 000000000..5903e54b0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/keyword_theme_constant_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + keyword_theme_constant_service, +) +from .base import KeywordThemeConstantServiceTransport, DEFAULT_CLIENT_INFO + + +class KeywordThemeConstantServiceGrpcTransport( + KeywordThemeConstantServiceTransport +): + """gRPC backend transport for KeywordThemeConstantService. + + Service to fetch Smart Campaign keyword themes. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def suggest_keyword_theme_constants( + self, + ) -> Callable[ + [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, + ]: + r"""Return a callable for the suggest keyword theme + constants method over gRPC. + + Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestKeywordThemeConstantsRequest], + ~.SuggestKeywordThemeConstantsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_theme_constants" not in self._stubs: + self._stubs[ + "suggest_keyword_theme_constants" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.KeywordThemeConstantService/SuggestKeywordThemeConstants", + request_serializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest.serialize, + response_deserializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse.deserialize, + ) + return self._stubs["suggest_keyword_theme_constants"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("KeywordThemeConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/label_service/__init__.py b/google/ads/googleads/v12/services/services/label_service/__init__.py new file mode 100644 index 000000000..1a6f2fa6d --- /dev/null +++ b/google/ads/googleads/v12/services/services/label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 LabelServiceClient + +__all__ = ("LabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/label_service/client.py b/google/ads/googleads/v12/services/services/label_service/client.py new file mode 100644 index 000000000..b4eccc617 --- /dev/null +++ b/google/ads/googleads/v12/services/services/label_service/client.py @@ -0,0 +1,483 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import LabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import LabelServiceGrpcTransport + + +class LabelServiceClientMeta(type): + """Metaclass for the LabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[LabelServiceTransport]] + _transport_registry["grpc"] = LabelServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[LabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class LabelServiceClient(metaclass=LabelServiceClientMeta): + """Service to manage labels.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> LabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + LabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def label_path(customer_id: str, label_id: str,) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, LabelServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, LabelServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, LabelServiceTransport): + # transport is a LabelServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_labels( + self, + request: Union[label_service.MutateLabelsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[label_service.LabelOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> label_service.MutateLabelsResponse: + r"""Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateLabelsRequest, dict]): + The request object. Request message for + [LabelService.MutateLabels][google.ads.googleads.v12.services.LabelService.MutateLabels]. + customer_id (str): + Required. ID of the customer whose + labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.LabelOperation]): + Required. The list of operations to + perform on labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateLabelsResponse: + Response message for a labels mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a label_service.MutateLabelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, label_service.MutateLabelsRequest): + request = label_service.MutateLabelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_labels] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("LabelServiceClient",) diff --git a/google/ads/googleads/v12/services/services/label_service/transports/__init__.py b/google/ads/googleads/v12/services/services/label_service/transports/__init__.py new file mode 100644 index 000000000..4d2b0c750 --- /dev/null +++ b/google/ads/googleads/v12/services/services/label_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 LabelServiceTransport +from .grpc import LabelServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[LabelServiceTransport]] +_transport_registry["grpc"] = LabelServiceGrpcTransport + +__all__ = ( + "LabelServiceTransport", + "LabelServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/label_service/transports/base.py b/google/ads/googleads/v12/services/services/label_service/transports/base.py new file mode 100644 index 000000000..525e8370a --- /dev/null +++ b/google/ads/googleads/v12/services/services/label_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import label_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class LabelServiceTransport(abc.ABC): + """Abstract transport class for LabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_labels: gapic_v1.method.wrap_method( + self.mutate_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_labels( + self, + ) -> Callable[ + [label_service.MutateLabelsRequest], + Union[ + label_service.MutateLabelsResponse, + Awaitable[label_service.MutateLabelsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("LabelServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/label_service/transports/grpc.py b/google/ads/googleads/v12/services/services/label_service/transports/grpc.py new file mode 100644 index 000000000..e5617e156 --- /dev/null +++ b/google/ads/googleads/v12/services/services/label_service/transports/grpc.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import label_service +from .base import LabelServiceTransport, DEFAULT_CLIENT_INFO + + +class LabelServiceGrpcTransport(LabelServiceTransport): + """gRPC backend transport for LabelService. + + Service to manage labels. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_labels( + self, + ) -> Callable[ + [label_service.MutateLabelsRequest], label_service.MutateLabelsResponse + ]: + r"""Return a callable for the mutate labels method over gRPC. + + Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateLabelsRequest], + ~.MutateLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_labels" not in self._stubs: + self._stubs["mutate_labels"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.LabelService/MutateLabels", + request_serializer=label_service.MutateLabelsRequest.serialize, + response_deserializer=label_service.MutateLabelsResponse.deserialize, + ) + return self._stubs["mutate_labels"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("LabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/media_file_service/__init__.py b/google/ads/googleads/v12/services/services/media_file_service/__init__.py new file mode 100644 index 000000000..c1376ca5d --- /dev/null +++ b/google/ads/googleads/v12/services/services/media_file_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MediaFileServiceClient + +__all__ = ("MediaFileServiceClient",) diff --git a/google/ads/googleads/v12/services/services/media_file_service/client.py b/google/ads/googleads/v12/services/services/media_file_service/client.py new file mode 100644 index 000000000..7034621ba --- /dev/null +++ b/google/ads/googleads/v12/services/services/media_file_service/client.py @@ -0,0 +1,486 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import media_file_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import MediaFileServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import MediaFileServiceGrpcTransport + + +class MediaFileServiceClientMeta(type): + """Metaclass for the MediaFileService 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[MediaFileServiceTransport]] + _transport_registry["grpc"] = MediaFileServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[MediaFileServiceTransport]: + """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 MediaFileServiceClient(metaclass=MediaFileServiceClientMeta): + """Service to manage media files.""" + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MediaFileServiceClient: 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: + MediaFileServiceClient: 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) -> MediaFileServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MediaFileServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def media_file_path(customer_id: str, media_file_id: str,) -> str: + """Returns a fully-qualified media_file string.""" + return "customers/{customer_id}/mediaFiles/{media_file_id}".format( + customer_id=customer_id, media_file_id=media_file_id, + ) + + @staticmethod + def parse_media_file_path(path: str) -> Dict[str, str]: + """Parses a media_file path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/mediaFiles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, MediaFileServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the media file 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 (Union[str, MediaFileServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, MediaFileServiceTransport): + # transport is a MediaFileServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_media_files( + self, + request: Union[media_file_service.MutateMediaFilesRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[media_file_service.MediaFileOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> media_file_service.MutateMediaFilesResponse: + r"""Creates media files. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `ImageError <>`__ `InternalError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateMediaFilesRequest, dict]): + The request object. Request message for + [MediaFileService.MutateMediaFiles][google.ads.googleads.v12.services.MediaFileService.MutateMediaFiles] + customer_id (str): + Required. The ID of the customer + whose media files are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.MediaFileOperation]): + Required. The list of operations to + perform on individual media file. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateMediaFilesResponse: + Response message for a media file + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a media_file_service.MutateMediaFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, media_file_service.MutateMediaFilesRequest): + request = media_file_service.MutateMediaFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_media_files + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("MediaFileServiceClient",) diff --git a/google/ads/googleads/v12/services/services/media_file_service/transports/__init__.py b/google/ads/googleads/v12/services/services/media_file_service/transports/__init__.py new file mode 100644 index 000000000..039538e1c --- /dev/null +++ b/google/ads/googleads/v12/services/services/media_file_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 MediaFileServiceTransport +from .grpc import MediaFileServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MediaFileServiceTransport]] +_transport_registry["grpc"] = MediaFileServiceGrpcTransport + +__all__ = ( + "MediaFileServiceTransport", + "MediaFileServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/media_file_service/transports/base.py b/google/ads/googleads/v12/services/services/media_file_service/transports/base.py new file mode 100644 index 000000000..ba570de83 --- /dev/null +++ b/google/ads/googleads/v12/services/services/media_file_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import media_file_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class MediaFileServiceTransport(abc.ABC): + """Abstract transport class for MediaFileService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_media_files: gapic_v1.method.wrap_method( + self.mutate_media_files, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_media_files( + self, + ) -> Callable[ + [media_file_service.MutateMediaFilesRequest], + Union[ + media_file_service.MutateMediaFilesResponse, + Awaitable[media_file_service.MutateMediaFilesResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("MediaFileServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/media_file_service/transports/grpc.py b/google/ads/googleads/v12/services/services/media_file_service/transports/grpc.py new file mode 100644 index 000000000..5c9977cc7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/media_file_service/transports/grpc.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import media_file_service +from .base import MediaFileServiceTransport, DEFAULT_CLIENT_INFO + + +class MediaFileServiceGrpcTransport(MediaFileServiceTransport): + """gRPC backend transport for MediaFileService. + + Service to manage media files. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_media_files( + self, + ) -> Callable[ + [media_file_service.MutateMediaFilesRequest], + media_file_service.MutateMediaFilesResponse, + ]: + r"""Return a callable for the mutate media files method over gRPC. + + Creates media files. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `ImageError <>`__ `InternalError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateMediaFilesRequest], + ~.MutateMediaFilesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_media_files" not in self._stubs: + self._stubs["mutate_media_files"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.MediaFileService/MutateMediaFiles", + request_serializer=media_file_service.MutateMediaFilesRequest.serialize, + response_deserializer=media_file_service.MutateMediaFilesResponse.deserialize, + ) + return self._stubs["mutate_media_files"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("MediaFileServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/merchant_center_link_service/__init__.py b/google/ads/googleads/v12/services/services/merchant_center_link_service/__init__.py new file mode 100644 index 000000000..01891e74e --- /dev/null +++ b/google/ads/googleads/v12/services/services/merchant_center_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MerchantCenterLinkServiceClient + +__all__ = ("MerchantCenterLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/merchant_center_link_service/client.py b/google/ads/googleads/v12/services/services/merchant_center_link_service/client.py new file mode 100644 index 000000000..37c92b26a --- /dev/null +++ b/google/ads/googleads/v12/services/services/merchant_center_link_service/client.py @@ -0,0 +1,673 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import merchant_center_link +from google.ads.googleads.v12.services.types import merchant_center_link_service +from .transports.base import ( + MerchantCenterLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import MerchantCenterLinkServiceGrpcTransport + + +class MerchantCenterLinkServiceClientMeta(type): + """Metaclass for the MerchantCenterLinkService 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[MerchantCenterLinkServiceTransport]] + _transport_registry["grpc"] = MerchantCenterLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[MerchantCenterLinkServiceTransport]: + """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 MerchantCenterLinkServiceClient( + metaclass=MerchantCenterLinkServiceClientMeta +): + """This service allows management of links between Google Ads + and Google Merchant Center. + """ + + @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") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + MerchantCenterLinkServiceClient: 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: + MerchantCenterLinkServiceClient: 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) -> MerchantCenterLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MerchantCenterLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def merchant_center_link_path( + customer_id: str, merchant_center_id: str, + ) -> str: + """Returns a fully-qualified merchant_center_link string.""" + return "customers/{customer_id}/merchantCenterLinks/{merchant_center_id}".format( + customer_id=customer_id, merchant_center_id=merchant_center_id, + ) + + @staticmethod + def parse_merchant_center_link_path(path: str) -> Dict[str, str]: + """Parses a merchant_center_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/merchantCenterLinks/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, MerchantCenterLinkServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the merchant center link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, MerchantCenterLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, MerchantCenterLinkServiceTransport): + # transport is a MerchantCenterLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def list_merchant_center_links( + self, + request: Union[ + merchant_center_link_service.ListMerchantCenterLinksRequest, dict + ] = None, + *, + customer_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_link_service.ListMerchantCenterLinksResponse: + r"""Returns Merchant Center links available for this customer. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListMerchantCenterLinksRequest, dict]): + The request object. Request message for + [MerchantCenterLinkService.ListMerchantCenterLinks][google.ads.googleads.v12.services.MerchantCenterLinkService.ListMerchantCenterLinks]. + customer_id (str): + Required. The ID of the customer onto + which to apply the Merchant Center link + list operation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListMerchantCenterLinksResponse: + Response message for + [MerchantCenterLinkService.ListMerchantCenterLinks][google.ads.googleads.v12.services.MerchantCenterLinkService.ListMerchantCenterLinks]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_link_service.ListMerchantCenterLinksRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, merchant_center_link_service.ListMerchantCenterLinksRequest + ): + request = merchant_center_link_service.ListMerchantCenterLinksRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_merchant_center_links + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def get_merchant_center_link( + self, + request: Union[ + merchant_center_link_service.GetMerchantCenterLinkRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_link.MerchantCenterLink: + r"""Returns the Merchant Center link in full detail. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GetMerchantCenterLinkRequest, dict]): + The request object. Request message for + [MerchantCenterLinkService.GetMerchantCenterLink][google.ads.googleads.v12.services.MerchantCenterLinkService.GetMerchantCenterLink]. + resource_name (str): + Required. Resource name of the + Merchant Center link. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.resources.types.MerchantCenterLink: + A data sharing connection, proposed + or in use, between a Google Ads Customer + and a Merchant Center account. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_link_service.GetMerchantCenterLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, merchant_center_link_service.GetMerchantCenterLinkRequest + ): + request = merchant_center_link_service.GetMerchantCenterLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_merchant_center_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate_merchant_center_link( + self, + request: Union[ + merchant_center_link_service.MutateMerchantCenterLinkRequest, dict + ] = None, + *, + customer_id: str = None, + operation: merchant_center_link_service.MerchantCenterLinkOperation = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> merchant_center_link_service.MutateMerchantCenterLinkResponse: + r"""Updates status or removes a Merchant Center link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateMerchantCenterLinkRequest, dict]): + The request object. Request message for + [MerchantCenterLinkService.MutateMerchantCenterLink][google.ads.googleads.v12.services.MerchantCenterLinkService.MutateMerchantCenterLink]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v12.services.types.MerchantCenterLinkOperation): + Required. The operation to perform on + the link + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateMerchantCenterLinkResponse: + Response message for Merchant Center + link mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operation]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a merchant_center_link_service.MutateMerchantCenterLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + merchant_center_link_service.MutateMerchantCenterLinkRequest, + ): + request = merchant_center_link_service.MutateMerchantCenterLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_merchant_center_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("MerchantCenterLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/__init__.py new file mode 100644 index 000000000..3c0a3fa88 --- /dev/null +++ b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 MerchantCenterLinkServiceTransport +from .grpc import MerchantCenterLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MerchantCenterLinkServiceTransport]] +_transport_registry["grpc"] = MerchantCenterLinkServiceGrpcTransport + +__all__ = ( + "MerchantCenterLinkServiceTransport", + "MerchantCenterLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/base.py b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/base.py new file mode 100644 index 000000000..defb573cb --- /dev/null +++ b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/base.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.resources.types import merchant_center_link +from google.ads.googleads.v12.services.types import merchant_center_link_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class MerchantCenterLinkServiceTransport(abc.ABC): + """Abstract transport class for MerchantCenterLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_merchant_center_links: gapic_v1.method.wrap_method( + self.list_merchant_center_links, + default_timeout=None, + client_info=client_info, + ), + self.get_merchant_center_link: gapic_v1.method.wrap_method( + self.get_merchant_center_link, + default_timeout=None, + client_info=client_info, + ), + self.mutate_merchant_center_link: gapic_v1.method.wrap_method( + self.mutate_merchant_center_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_merchant_center_links( + self, + ) -> Callable[ + [merchant_center_link_service.ListMerchantCenterLinksRequest], + Union[ + merchant_center_link_service.ListMerchantCenterLinksResponse, + Awaitable[ + merchant_center_link_service.ListMerchantCenterLinksResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def get_merchant_center_link( + self, + ) -> Callable[ + [merchant_center_link_service.GetMerchantCenterLinkRequest], + Union[ + merchant_center_link.MerchantCenterLink, + Awaitable[merchant_center_link.MerchantCenterLink], + ], + ]: + raise NotImplementedError() + + @property + def mutate_merchant_center_link( + self, + ) -> Callable[ + [merchant_center_link_service.MutateMerchantCenterLinkRequest], + Union[ + merchant_center_link_service.MutateMerchantCenterLinkResponse, + Awaitable[ + merchant_center_link_service.MutateMerchantCenterLinkResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("MerchantCenterLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/grpc.py new file mode 100644 index 000000000..00ad36c02 --- /dev/null +++ b/google/ads/googleads/v12/services/services/merchant_center_link_service/transports/grpc.py @@ -0,0 +1,349 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.resources.types import merchant_center_link +from google.ads.googleads.v12.services.types import merchant_center_link_service +from .base import MerchantCenterLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class MerchantCenterLinkServiceGrpcTransport( + MerchantCenterLinkServiceTransport +): + """gRPC backend transport for MerchantCenterLinkService. + + This service allows management of links between Google Ads + and Google Merchant Center. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def list_merchant_center_links( + self, + ) -> Callable[ + [merchant_center_link_service.ListMerchantCenterLinksRequest], + merchant_center_link_service.ListMerchantCenterLinksResponse, + ]: + r"""Return a callable for the list merchant center links method over gRPC. + + Returns Merchant Center links available for this customer. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListMerchantCenterLinksRequest], + ~.ListMerchantCenterLinksResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_merchant_center_links" not in self._stubs: + self._stubs[ + "list_merchant_center_links" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.MerchantCenterLinkService/ListMerchantCenterLinks", + request_serializer=merchant_center_link_service.ListMerchantCenterLinksRequest.serialize, + response_deserializer=merchant_center_link_service.ListMerchantCenterLinksResponse.deserialize, + ) + return self._stubs["list_merchant_center_links"] + + @property + def get_merchant_center_link( + self, + ) -> Callable[ + [merchant_center_link_service.GetMerchantCenterLinkRequest], + merchant_center_link.MerchantCenterLink, + ]: + r"""Return a callable for the get merchant center link method over gRPC. + + Returns the Merchant Center link in full detail. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetMerchantCenterLinkRequest], + ~.MerchantCenterLink]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_merchant_center_link" not in self._stubs: + self._stubs[ + "get_merchant_center_link" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.MerchantCenterLinkService/GetMerchantCenterLink", + request_serializer=merchant_center_link_service.GetMerchantCenterLinkRequest.serialize, + response_deserializer=merchant_center_link.MerchantCenterLink.deserialize, + ) + return self._stubs["get_merchant_center_link"] + + @property + def mutate_merchant_center_link( + self, + ) -> Callable[ + [merchant_center_link_service.MutateMerchantCenterLinkRequest], + merchant_center_link_service.MutateMerchantCenterLinkResponse, + ]: + r"""Return a callable for the mutate merchant center link method over gRPC. + + Updates status or removes a Merchant Center link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateMerchantCenterLinkRequest], + ~.MutateMerchantCenterLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_merchant_center_link" not in self._stubs: + self._stubs[ + "mutate_merchant_center_link" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.MerchantCenterLinkService/MutateMerchantCenterLink", + request_serializer=merchant_center_link_service.MutateMerchantCenterLinkRequest.serialize, + response_deserializer=merchant_center_link_service.MutateMerchantCenterLinkResponse.deserialize, + ) + return self._stubs["mutate_merchant_center_link"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("MerchantCenterLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/offline_user_data_job_service/__init__.py b/google/ads/googleads/v12/services/services/offline_user_data_job_service/__init__.py new file mode 100644 index 000000000..e65276419 --- /dev/null +++ b/google/ads/googleads/v12/services/services/offline_user_data_job_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 OfflineUserDataJobServiceClient + +__all__ = ("OfflineUserDataJobServiceClient",) diff --git a/google/ads/googleads/v12/services/services/offline_user_data_job_service/client.py b/google/ads/googleads/v12/services/services/offline_user_data_job_service/client.py new file mode 100644 index 000000000..322e9d8b7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/offline_user_data_job_service/client.py @@ -0,0 +1,717 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.resources.types import offline_user_data_job +from google.ads.googleads.v12.services.types import ( + offline_user_data_job_service, +) +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + OfflineUserDataJobServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import OfflineUserDataJobServiceGrpcTransport + + +class OfflineUserDataJobServiceClientMeta(type): + """Metaclass for the OfflineUserDataJobService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[OfflineUserDataJobServiceTransport]] + _transport_registry["grpc"] = OfflineUserDataJobServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[OfflineUserDataJobServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class OfflineUserDataJobServiceClient( + metaclass=OfflineUserDataJobServiceClientMeta +): + """Service to manage offline user data jobs.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> OfflineUserDataJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + OfflineUserDataJobServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def offline_user_data_job_path( + customer_id: str, offline_user_data_update_id: str, + ) -> str: + """Returns a fully-qualified offline_user_data_job string.""" + return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( + customer_id=customer_id, + offline_user_data_update_id=offline_user_data_update_id, + ) + + @staticmethod + def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: + """Parses a offline_user_data_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, OfflineUserDataJobServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the offline user data job service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, OfflineUserDataJobServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, OfflineUserDataJobServiceTransport): + # transport is a OfflineUserDataJobServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def create_offline_user_data_job( + self, + request: Union[ + offline_user_data_job_service.CreateOfflineUserDataJobRequest, dict + ] = None, + *, + customer_id: str = None, + job: offline_user_data_job.OfflineUserDataJob = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> offline_user_data_job_service.CreateOfflineUserDataJobResponse: + r"""Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.CreateOfflineUserDataJobRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + customer_id (str): + Required. The ID of the customer for + which to create an offline user data + job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + job (google.ads.googleads.v12.resources.types.OfflineUserDataJob): + Required. The offline user data job + to be created. + + This corresponds to the ``job`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.CreateOfflineUserDataJobResponse: + Response message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, job]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a offline_user_data_job_service.CreateOfflineUserDataJobRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + offline_user_data_job_service.CreateOfflineUserDataJobRequest, + ): + request = offline_user_data_job_service.CreateOfflineUserDataJobRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if job is not None: + request.job = job + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def add_offline_user_data_job_operations( + self, + request: Union[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + dict, + ] = None, + *, + resource_name: str = None, + operations: Sequence[ + offline_user_data_job_service.OfflineUserDataJobOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse: + r"""Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.AddOfflineUserDataJobOperationsRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v12.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + resource_name (str): + Required. The resource name of the + OfflineUserDataJob. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.OfflineUserDataJobOperation]): + Required. The list of operations to + be done. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.AddOfflineUserDataJobOperationsResponse: + Response message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v12.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + ): + request = offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.add_offline_user_data_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def run_offline_user_data_job( + self, + request: Union[ + offline_user_data_job_service.RunOfflineUserDataJobRequest, dict + ] = None, + *, + resource_name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.RunOfflineUserDataJobRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.RunOfflineUserDataJob]. + resource_name (str): + Required. The resource name of the + OfflineUserDataJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a offline_user_data_job_service.RunOfflineUserDataJobRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, offline_user_data_job_service.RunOfflineUserDataJobRequest + ): + request = offline_user_data_job_service.RunOfflineUserDataJobRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.run_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=offline_user_data_job.OfflineUserDataJobMetadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("OfflineUserDataJobServiceClient",) diff --git a/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/__init__.py b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/__init__.py new file mode 100644 index 000000000..837aaaa40 --- /dev/null +++ b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 OfflineUserDataJobServiceTransport +from .grpc import OfflineUserDataJobServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[OfflineUserDataJobServiceTransport]] +_transport_registry["grpc"] = OfflineUserDataJobServiceGrpcTransport + +__all__ = ( + "OfflineUserDataJobServiceTransport", + "OfflineUserDataJobServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/base.py b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/base.py new file mode 100644 index 000000000..44cf454d7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + offline_user_data_job_service, +) +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class OfflineUserDataJobServiceTransport(abc.ABC): + """Abstract transport class for OfflineUserDataJobService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_offline_user_data_job: gapic_v1.method.wrap_method( + self.create_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + self.add_offline_user_data_job_operations: gapic_v1.method.wrap_method( + self.add_offline_user_data_job_operations, + default_timeout=None, + client_info=client_info, + ), + self.run_offline_user_data_job: gapic_v1.method.wrap_method( + self.run_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.CreateOfflineUserDataJobRequest], + Union[ + offline_user_data_job_service.CreateOfflineUserDataJobResponse, + Awaitable[ + offline_user_data_job_service.CreateOfflineUserDataJobResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def add_offline_user_data_job_operations( + self, + ) -> Callable[ + [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], + Union[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, + Awaitable[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def run_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.RunOfflineUserDataJobRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + +__all__ = ("OfflineUserDataJobServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/grpc.py b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/grpc.py new file mode 100644 index 000000000..133dc9848 --- /dev/null +++ b/google/ads/googleads/v12/services/services/offline_user_data_job_service/transports/grpc.py @@ -0,0 +1,377 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + offline_user_data_job_service, +) +from google.longrunning import operations_pb2 # type: ignore +from .base import OfflineUserDataJobServiceTransport, DEFAULT_CLIENT_INFO + + +class OfflineUserDataJobServiceGrpcTransport( + OfflineUserDataJobServiceTransport +): + """gRPC backend transport for OfflineUserDataJobService. + + Service to manage offline user data jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: 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 channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.CreateOfflineUserDataJobRequest], + offline_user_data_job_service.CreateOfflineUserDataJobResponse, + ]: + r"""Return a callable for the create offline user data job method over gRPC. + + Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.CreateOfflineUserDataJobRequest], + ~.CreateOfflineUserDataJobResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_offline_user_data_job" not in self._stubs: + self._stubs[ + "create_offline_user_data_job" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.OfflineUserDataJobService/CreateOfflineUserDataJob", + request_serializer=offline_user_data_job_service.CreateOfflineUserDataJobRequest.serialize, + response_deserializer=offline_user_data_job_service.CreateOfflineUserDataJobResponse.deserialize, + ) + return self._stubs["create_offline_user_data_job"] + + @property + def add_offline_user_data_job_operations( + self, + ) -> Callable[ + [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, + ]: + r"""Return a callable for the add offline user data job + operations method over gRPC. + + Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.AddOfflineUserDataJobOperationsRequest], + ~.AddOfflineUserDataJobOperationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_offline_user_data_job_operations" not in self._stubs: + self._stubs[ + "add_offline_user_data_job_operations" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.OfflineUserDataJobService/AddOfflineUserDataJobOperations", + request_serializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest.serialize, + response_deserializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse.deserialize, + ) + return self._stubs["add_offline_user_data_job_operations"] + + @property + def run_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.RunOfflineUserDataJobRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the run offline user data job method over gRPC. + + Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunOfflineUserDataJobRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_offline_user_data_job" not in self._stubs: + self._stubs[ + "run_offline_user_data_job" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.OfflineUserDataJobService/RunOfflineUserDataJob", + request_serializer=offline_user_data_job_service.RunOfflineUserDataJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["run_offline_user_data_job"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("OfflineUserDataJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/payments_account_service/__init__.py b/google/ads/googleads/v12/services/services/payments_account_service/__init__.py new file mode 100644 index 000000000..73b3cb89e --- /dev/null +++ b/google/ads/googleads/v12/services/services/payments_account_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 PaymentsAccountServiceClient + +__all__ = ("PaymentsAccountServiceClient",) diff --git a/google/ads/googleads/v12/services/services/payments_account_service/client.py b/google/ads/googleads/v12/services/services/payments_account_service/client.py new file mode 100644 index 000000000..44d4f16b5 --- /dev/null +++ b/google/ads/googleads/v12/services/services/payments_account_service/client.py @@ -0,0 +1,497 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import payments_account_service +from .transports.base import ( + PaymentsAccountServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import PaymentsAccountServiceGrpcTransport + + +class PaymentsAccountServiceClientMeta(type): + """Metaclass for the PaymentsAccountService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[PaymentsAccountServiceTransport]] + _transport_registry["grpc"] = PaymentsAccountServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[PaymentsAccountServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class PaymentsAccountServiceClient(metaclass=PaymentsAccountServiceClientMeta): + """Service to provide payments accounts that can be used to set + up consolidated billing. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> PaymentsAccountServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PaymentsAccountServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def customer_path(customer_id: str,) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format(customer_id=customer_id,) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, PaymentsAccountServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the payments account service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, PaymentsAccountServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, PaymentsAccountServiceTransport): + # transport is a PaymentsAccountServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def list_payments_accounts( + self, + request: Union[ + payments_account_service.ListPaymentsAccountsRequest, dict + ] = None, + *, + customer_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> payments_account_service.ListPaymentsAccountsResponse: + r"""Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListPaymentsAccountsRequest, dict]): + The request object. Request message for fetching all + accessible payments accounts. + customer_id (str): + Required. The ID of the customer to + apply the PaymentsAccount list operation + to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListPaymentsAccountsResponse: + Response message for + [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v12.services.PaymentsAccountService.ListPaymentsAccounts]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a payments_account_service.ListPaymentsAccountsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, payments_account_service.ListPaymentsAccountsRequest + ): + request = payments_account_service.ListPaymentsAccountsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_payments_accounts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("PaymentsAccountServiceClient",) diff --git a/google/ads/googleads/v12/services/services/payments_account_service/transports/__init__.py b/google/ads/googleads/v12/services/services/payments_account_service/transports/__init__.py new file mode 100644 index 000000000..752a5cfb8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/payments_account_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 PaymentsAccountServiceTransport +from .grpc import PaymentsAccountServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[PaymentsAccountServiceTransport]] +_transport_registry["grpc"] = PaymentsAccountServiceGrpcTransport + +__all__ = ( + "PaymentsAccountServiceTransport", + "PaymentsAccountServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/payments_account_service/transports/base.py b/google/ads/googleads/v12/services/services/payments_account_service/transports/base.py new file mode 100644 index 000000000..cfcc426b1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/payments_account_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import payments_account_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class PaymentsAccountServiceTransport(abc.ABC): + """Abstract transport class for PaymentsAccountService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_payments_accounts: gapic_v1.method.wrap_method( + self.list_payments_accounts, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_payments_accounts( + self, + ) -> Callable[ + [payments_account_service.ListPaymentsAccountsRequest], + Union[ + payments_account_service.ListPaymentsAccountsResponse, + Awaitable[payments_account_service.ListPaymentsAccountsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("PaymentsAccountServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/payments_account_service/transports/grpc.py b/google/ads/googleads/v12/services/services/payments_account_service/transports/grpc.py new file mode 100644 index 000000000..c21c029a1 --- /dev/null +++ b/google/ads/googleads/v12/services/services/payments_account_service/transports/grpc.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import payments_account_service +from .base import PaymentsAccountServiceTransport, DEFAULT_CLIENT_INFO + + +class PaymentsAccountServiceGrpcTransport(PaymentsAccountServiceTransport): + """gRPC backend transport for PaymentsAccountService. + + Service to provide payments accounts that can be used to set + up consolidated billing. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def list_payments_accounts( + self, + ) -> Callable[ + [payments_account_service.ListPaymentsAccountsRequest], + payments_account_service.ListPaymentsAccountsResponse, + ]: + r"""Return a callable for the list payments accounts method over gRPC. + + Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPaymentsAccountsRequest], + ~.ListPaymentsAccountsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_payments_accounts" not in self._stubs: + self._stubs[ + "list_payments_accounts" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.PaymentsAccountService/ListPaymentsAccounts", + request_serializer=payments_account_service.ListPaymentsAccountsRequest.serialize, + response_deserializer=payments_account_service.ListPaymentsAccountsResponse.deserialize, + ) + return self._stubs["list_payments_accounts"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("PaymentsAccountServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/reach_plan_service/__init__.py b/google/ads/googleads/v12/services/services/reach_plan_service/__init__.py new file mode 100644 index 000000000..48d2d1911 --- /dev/null +++ b/google/ads/googleads/v12/services/services/reach_plan_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ReachPlanServiceClient + +__all__ = ("ReachPlanServiceClient",) diff --git a/google/ads/googleads/v12/services/services/reach_plan_service/client.py b/google/ads/googleads/v12/services/services/reach_plan_service/client.py new file mode 100644 index 000000000..8d7f23e5a --- /dev/null +++ b/google/ads/googleads/v12/services/services/reach_plan_service/client.py @@ -0,0 +1,617 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import reach_plan_service +from .transports.base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ReachPlanServiceGrpcTransport + + +class ReachPlanServiceClientMeta(type): + """Metaclass for the ReachPlanService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ReachPlanServiceTransport]] + _transport_registry["grpc"] = ReachPlanServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ReachPlanServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ReachPlanServiceClient(metaclass=ReachPlanServiceClientMeta): + """Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ReachPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ReachPlanServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ReachPlanServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the reach plan service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ReachPlanServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ReachPlanServiceTransport): + # transport is a ReachPlanServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def list_plannable_locations( + self, + request: Union[ + reach_plan_service.ListPlannableLocationsRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> reach_plan_service.ListPlannableLocationsResponse: + r"""Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListPlannableLocationsRequest, dict]): + The request object. Request message for + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListPlannableLocationsResponse: + The list of plannable locations. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a reach_plan_service.ListPlannableLocationsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, reach_plan_service.ListPlannableLocationsRequest + ): + request = reach_plan_service.ListPlannableLocationsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_locations + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_plannable_products( + self, + request: Union[ + reach_plan_service.ListPlannableProductsRequest, dict + ] = None, + *, + plannable_location_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> reach_plan_service.ListPlannableProductsResponse: + r"""Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ListPlannableProductsRequest, dict]): + The request object. Request to list available products + in a given location. + plannable_location_id (str): + Required. The ID of the selected location for planning. + To list the available plannable location IDs use + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + + This corresponds to the ``plannable_location_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ListPlannableProductsResponse: + A response with all available + products. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([plannable_location_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a reach_plan_service.ListPlannableProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, reach_plan_service.ListPlannableProductsRequest + ): + request = reach_plan_service.ListPlannableProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if plannable_location_id is not None: + request.plannable_location_id = plannable_location_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_products + ] + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_reach_forecast( + self, + request: Union[ + reach_plan_service.GenerateReachForecastRequest, dict + ] = None, + *, + customer_id: str = None, + campaign_duration: reach_plan_service.CampaignDuration = None, + planned_products: Sequence[reach_plan_service.PlannedProduct] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> reach_plan_service.GenerateReachForecastResponse: + r"""Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.GenerateReachForecastRequest, dict]): + The request object. Request message for + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v12.services.ReachPlanService.GenerateReachForecast]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_duration (google.ads.googleads.v12.services.types.CampaignDuration): + Required. Campaign duration. + This corresponds to the ``campaign_duration`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + planned_products (Sequence[google.ads.googleads.v12.services.types.PlannedProduct]): + Required. The products to be + forecast. The max number of allowed + planned products is 15. + + This corresponds to the ``planned_products`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.GenerateReachForecastResponse: + Response message containing the + generated reach curve. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [customer_id, campaign_duration, planned_products] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a reach_plan_service.GenerateReachForecastRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, reach_plan_service.GenerateReachForecastRequest + ): + request = reach_plan_service.GenerateReachForecastRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if campaign_duration is not None: + request.campaign_duration = campaign_duration + if planned_products is not None: + request.planned_products = planned_products + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_reach_forecast + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ReachPlanServiceClient",) diff --git a/google/ads/googleads/v12/services/services/reach_plan_service/transports/__init__.py b/google/ads/googleads/v12/services/services/reach_plan_service/transports/__init__.py new file mode 100644 index 000000000..a296277b7 --- /dev/null +++ b/google/ads/googleads/v12/services/services/reach_plan_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ReachPlanServiceTransport +from .grpc import ReachPlanServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ReachPlanServiceTransport]] +_transport_registry["grpc"] = ReachPlanServiceGrpcTransport + +__all__ = ( + "ReachPlanServiceTransport", + "ReachPlanServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/reach_plan_service/transports/base.py b/google/ads/googleads/v12/services/services/reach_plan_service/transports/base.py new file mode 100644 index 000000000..2183123c0 --- /dev/null +++ b/google/ads/googleads/v12/services/services/reach_plan_service/transports/base.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import reach_plan_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ReachPlanServiceTransport(abc.ABC): + """Abstract transport class for ReachPlanService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_plannable_locations: gapic_v1.method.wrap_method( + self.list_plannable_locations, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_products: gapic_v1.method.wrap_method( + self.list_plannable_products, + default_timeout=None, + client_info=client_info, + ), + self.generate_reach_forecast: gapic_v1.method.wrap_method( + self.generate_reach_forecast, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_plannable_locations( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableLocationsRequest], + Union[ + reach_plan_service.ListPlannableLocationsResponse, + Awaitable[reach_plan_service.ListPlannableLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_plannable_products( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableProductsRequest], + Union[ + reach_plan_service.ListPlannableProductsResponse, + Awaitable[reach_plan_service.ListPlannableProductsResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_reach_forecast( + self, + ) -> Callable[ + [reach_plan_service.GenerateReachForecastRequest], + Union[ + reach_plan_service.GenerateReachForecastResponse, + Awaitable[reach_plan_service.GenerateReachForecastResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ReachPlanServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/reach_plan_service/transports/grpc.py b/google/ads/googleads/v12/services/services/reach_plan_service/transports/grpc.py new file mode 100644 index 000000000..9a674abfa --- /dev/null +++ b/google/ads/googleads/v12/services/services/reach_plan_service/transports/grpc.py @@ -0,0 +1,352 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import reach_plan_service +from .base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO + + +class ReachPlanServiceGrpcTransport(ReachPlanServiceTransport): + """gRPC backend transport for ReachPlanService. + + Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def list_plannable_locations( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableLocationsRequest], + reach_plan_service.ListPlannableLocationsResponse, + ]: + r"""Return a callable for the list plannable locations method over gRPC. + + Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableLocationsRequest], + ~.ListPlannableLocationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_locations" not in self._stubs: + self._stubs[ + "list_plannable_locations" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ReachPlanService/ListPlannableLocations", + request_serializer=reach_plan_service.ListPlannableLocationsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableLocationsResponse.deserialize, + ) + return self._stubs["list_plannable_locations"] + + @property + def list_plannable_products( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableProductsRequest], + reach_plan_service.ListPlannableProductsResponse, + ]: + r"""Return a callable for the list plannable products method over gRPC. + + Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableProductsRequest], + ~.ListPlannableProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_products" not in self._stubs: + self._stubs[ + "list_plannable_products" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ReachPlanService/ListPlannableProducts", + request_serializer=reach_plan_service.ListPlannableProductsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableProductsResponse.deserialize, + ) + return self._stubs["list_plannable_products"] + + @property + def generate_reach_forecast( + self, + ) -> Callable[ + [reach_plan_service.GenerateReachForecastRequest], + reach_plan_service.GenerateReachForecastResponse, + ]: + r"""Return a callable for the generate reach forecast method over gRPC. + + Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateReachForecastRequest], + ~.GenerateReachForecastResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_reach_forecast" not in self._stubs: + self._stubs[ + "generate_reach_forecast" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ReachPlanService/GenerateReachForecast", + request_serializer=reach_plan_service.GenerateReachForecastRequest.serialize, + response_deserializer=reach_plan_service.GenerateReachForecastResponse.deserialize, + ) + return self._stubs["generate_reach_forecast"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ReachPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/recommendation_service/__init__.py b/google/ads/googleads/v12/services/services/recommendation_service/__init__.py new file mode 100644 index 000000000..27e2df7bc --- /dev/null +++ b/google/ads/googleads/v12/services/services/recommendation_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 RecommendationServiceClient + +__all__ = ("RecommendationServiceClient",) diff --git a/google/ads/googleads/v12/services/services/recommendation_service/client.py b/google/ads/googleads/v12/services/services/recommendation_service/client.py new file mode 100644 index 000000000..7abdfc3be --- /dev/null +++ b/google/ads/googleads/v12/services/services/recommendation_service/client.py @@ -0,0 +1,608 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import recommendation_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import RecommendationServiceGrpcTransport + + +class RecommendationServiceClientMeta(type): + """Metaclass for the RecommendationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[RecommendationServiceTransport]] + _transport_registry["grpc"] = RecommendationServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[RecommendationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class RecommendationServiceClient(metaclass=RecommendationServiceClientMeta): + """Service to manage recommendations.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> RecommendationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RecommendationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def ad_path(customer_id: str, ad_id: str,) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_path(customer_id: str, recommendation_id: str,) -> str: + """Returns a fully-qualified recommendation string.""" + return "customers/{customer_id}/recommendations/{recommendation_id}".format( + customer_id=customer_id, recommendation_id=recommendation_id, + ) + + @staticmethod + def parse_recommendation_path(path: str) -> Dict[str, str]: + """Parses a recommendation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, RecommendationServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the recommendation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, RecommendationServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, RecommendationServiceTransport): + # transport is a RecommendationServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def apply_recommendation( + self, + request: Union[ + recommendation_service.ApplyRecommendationRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + recommendation_service.ApplyRecommendationOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> recommendation_service.ApplyRecommendationResponse: + r"""Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.ApplyRecommendationRequest, dict]): + The request object. Request message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v12.services.RecommendationService.ApplyRecommendation]. + customer_id (str): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.ApplyRecommendationOperation]): + Required. The list of operations to apply + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.ApplyRecommendationResponse: + Response message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v12.services.RecommendationService.ApplyRecommendation]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a recommendation_service.ApplyRecommendationRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, recommendation_service.ApplyRecommendationRequest + ): + request = recommendation_service.ApplyRecommendationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.apply_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def dismiss_recommendation( + self, + request: Union[ + recommendation_service.DismissRecommendationRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + recommendation_service.DismissRecommendationRequest.DismissRecommendationOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> recommendation_service.DismissRecommendationResponse: + r"""Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.DismissRecommendationRequest, dict]): + The request object. Request message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v12.services.RecommendationService.DismissRecommendation]. + customer_id (str): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): + Required. The list of operations to dismiss + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.DismissRecommendationResponse: + Response message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v12.services.RecommendationService.DismissRecommendation]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a recommendation_service.DismissRecommendationRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, recommendation_service.DismissRecommendationRequest + ): + request = recommendation_service.DismissRecommendationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.dismiss_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("RecommendationServiceClient",) diff --git a/google/ads/googleads/v12/services/services/recommendation_service/transports/__init__.py b/google/ads/googleads/v12/services/services/recommendation_service/transports/__init__.py new file mode 100644 index 000000000..c4ad2ccee --- /dev/null +++ b/google/ads/googleads/v12/services/services/recommendation_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 RecommendationServiceTransport +from .grpc import RecommendationServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[RecommendationServiceTransport]] +_transport_registry["grpc"] = RecommendationServiceGrpcTransport + +__all__ = ( + "RecommendationServiceTransport", + "RecommendationServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/recommendation_service/transports/base.py b/google/ads/googleads/v12/services/services/recommendation_service/transports/base.py new file mode 100644 index 000000000..e3335f347 --- /dev/null +++ b/google/ads/googleads/v12/services/services/recommendation_service/transports/base.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import recommendation_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class RecommendationServiceTransport(abc.ABC): + """Abstract transport class for RecommendationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.apply_recommendation: gapic_v1.method.wrap_method( + self.apply_recommendation, + default_timeout=None, + client_info=client_info, + ), + self.dismiss_recommendation: gapic_v1.method.wrap_method( + self.dismiss_recommendation, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def apply_recommendation( + self, + ) -> Callable[ + [recommendation_service.ApplyRecommendationRequest], + Union[ + recommendation_service.ApplyRecommendationResponse, + Awaitable[recommendation_service.ApplyRecommendationResponse], + ], + ]: + raise NotImplementedError() + + @property + def dismiss_recommendation( + self, + ) -> Callable[ + [recommendation_service.DismissRecommendationRequest], + Union[ + recommendation_service.DismissRecommendationResponse, + Awaitable[recommendation_service.DismissRecommendationResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("RecommendationServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/recommendation_service/transports/grpc.py b/google/ads/googleads/v12/services/services/recommendation_service/transports/grpc.py new file mode 100644 index 000000000..64e431c7e --- /dev/null +++ b/google/ads/googleads/v12/services/services/recommendation_service/transports/grpc.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import recommendation_service +from .base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO + + +class RecommendationServiceGrpcTransport(RecommendationServiceTransport): + """gRPC backend transport for RecommendationService. + + Service to manage recommendations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def apply_recommendation( + self, + ) -> Callable[ + [recommendation_service.ApplyRecommendationRequest], + recommendation_service.ApplyRecommendationResponse, + ]: + r"""Return a callable for the apply recommendation method over gRPC. + + Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.ApplyRecommendationRequest], + ~.ApplyRecommendationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "apply_recommendation" not in self._stubs: + self._stubs["apply_recommendation"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.RecommendationService/ApplyRecommendation", + request_serializer=recommendation_service.ApplyRecommendationRequest.serialize, + response_deserializer=recommendation_service.ApplyRecommendationResponse.deserialize, + ) + return self._stubs["apply_recommendation"] + + @property + def dismiss_recommendation( + self, + ) -> Callable[ + [recommendation_service.DismissRecommendationRequest], + recommendation_service.DismissRecommendationResponse, + ]: + r"""Return a callable for the dismiss recommendation method over gRPC. + + Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.DismissRecommendationRequest], + ~.DismissRecommendationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "dismiss_recommendation" not in self._stubs: + self._stubs[ + "dismiss_recommendation" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.RecommendationService/DismissRecommendation", + request_serializer=recommendation_service.DismissRecommendationRequest.serialize, + response_deserializer=recommendation_service.DismissRecommendationResponse.deserialize, + ) + return self._stubs["dismiss_recommendation"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("RecommendationServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/remarketing_action_service/__init__.py b/google/ads/googleads/v12/services/services/remarketing_action_service/__init__.py new file mode 100644 index 000000000..8db817b7a --- /dev/null +++ b/google/ads/googleads/v12/services/services/remarketing_action_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 RemarketingActionServiceClient + +__all__ = ("RemarketingActionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/remarketing_action_service/client.py b/google/ads/googleads/v12/services/services/remarketing_action_service/client.py new file mode 100644 index 000000000..207ebbd6f --- /dev/null +++ b/google/ads/googleads/v12/services/services/remarketing_action_service/client.py @@ -0,0 +1,500 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import remarketing_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + RemarketingActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import RemarketingActionServiceGrpcTransport + + +class RemarketingActionServiceClientMeta(type): + """Metaclass for the RemarketingActionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[RemarketingActionServiceTransport]] + _transport_registry["grpc"] = RemarketingActionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[RemarketingActionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class RemarketingActionServiceClient( + metaclass=RemarketingActionServiceClientMeta +): + """Service to manage remarketing actions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> RemarketingActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RemarketingActionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def remarketing_action_path( + customer_id: str, remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, RemarketingActionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the remarketing action service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, RemarketingActionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, RemarketingActionServiceTransport): + # transport is a RemarketingActionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_remarketing_actions( + self, + request: Union[ + remarketing_action_service.MutateRemarketingActionsRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + remarketing_action_service.RemarketingActionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> remarketing_action_service.MutateRemarketingActionsResponse: + r"""Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateRemarketingActionsRequest, dict]): + The request object. Request message for + [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v12.services.RemarketingActionService.MutateRemarketingActions]. + customer_id (str): + Required. The ID of the customer + whose remarketing actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.RemarketingActionOperation]): + Required. The list of operations to + perform on individual remarketing + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateRemarketingActionsResponse: + Response message for remarketing + action mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a remarketing_action_service.MutateRemarketingActionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, remarketing_action_service.MutateRemarketingActionsRequest + ): + request = remarketing_action_service.MutateRemarketingActionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_remarketing_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("RemarketingActionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/remarketing_action_service/transports/__init__.py b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/__init__.py new file mode 100644 index 000000000..d3829434e --- /dev/null +++ b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 RemarketingActionServiceTransport +from .grpc import RemarketingActionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[RemarketingActionServiceTransport]] +_transport_registry["grpc"] = RemarketingActionServiceGrpcTransport + +__all__ = ( + "RemarketingActionServiceTransport", + "RemarketingActionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/remarketing_action_service/transports/base.py b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/base.py new file mode 100644 index 000000000..c4c87f457 --- /dev/null +++ b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import remarketing_action_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class RemarketingActionServiceTransport(abc.ABC): + """Abstract transport class for RemarketingActionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_remarketing_actions: gapic_v1.method.wrap_method( + self.mutate_remarketing_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_remarketing_actions( + self, + ) -> Callable[ + [remarketing_action_service.MutateRemarketingActionsRequest], + Union[ + remarketing_action_service.MutateRemarketingActionsResponse, + Awaitable[ + remarketing_action_service.MutateRemarketingActionsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("RemarketingActionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/remarketing_action_service/transports/grpc.py b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/grpc.py new file mode 100644 index 000000000..a6df30e94 --- /dev/null +++ b/google/ads/googleads/v12/services/services/remarketing_action_service/transports/grpc.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import remarketing_action_service +from .base import RemarketingActionServiceTransport, DEFAULT_CLIENT_INFO + + +class RemarketingActionServiceGrpcTransport(RemarketingActionServiceTransport): + """gRPC backend transport for RemarketingActionService. + + Service to manage remarketing actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_remarketing_actions( + self, + ) -> Callable[ + [remarketing_action_service.MutateRemarketingActionsRequest], + remarketing_action_service.MutateRemarketingActionsResponse, + ]: + r"""Return a callable for the mutate remarketing actions method over gRPC. + + Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateRemarketingActionsRequest], + ~.MutateRemarketingActionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_remarketing_actions" not in self._stubs: + self._stubs[ + "mutate_remarketing_actions" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.RemarketingActionService/MutateRemarketingActions", + request_serializer=remarketing_action_service.MutateRemarketingActionsRequest.serialize, + response_deserializer=remarketing_action_service.MutateRemarketingActionsResponse.deserialize, + ) + return self._stubs["mutate_remarketing_actions"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("RemarketingActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/shared_criterion_service/__init__.py b/google/ads/googleads/v12/services/services/shared_criterion_service/__init__.py new file mode 100644 index 000000000..4bc8ba887 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_criterion_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 SharedCriterionServiceClient + +__all__ = ("SharedCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/shared_criterion_service/client.py b/google/ads/googleads/v12/services/services/shared_criterion_service/client.py new file mode 100644 index 000000000..1a9ba74bc --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_criterion_service/client.py @@ -0,0 +1,519 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import shared_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SharedCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SharedCriterionServiceGrpcTransport + + +class SharedCriterionServiceClientMeta(type): + """Metaclass for the SharedCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SharedCriterionServiceTransport]] + _transport_registry["grpc"] = SharedCriterionServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[SharedCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SharedCriterionServiceClient(metaclass=SharedCriterionServiceClientMeta): + """Service to manage shared criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SharedCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def shared_criterion_path( + customer_id: str, shared_set_id: str, criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path(customer_id: str, shared_set_id: str,) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SharedCriterionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SharedCriterionServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SharedCriterionServiceTransport): + # transport is a SharedCriterionServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_shared_criteria( + self, + request: Union[ + shared_criterion_service.MutateSharedCriteriaRequest, dict + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + shared_criterion_service.SharedCriterionOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> shared_criterion_service.MutateSharedCriteriaResponse: + r"""Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateSharedCriteriaRequest, dict]): + The request object. Request message for + [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v12.services.SharedCriterionService.MutateSharedCriteria]. + customer_id (str): + Required. The ID of the customer + whose shared criteria are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.SharedCriterionOperation]): + Required. The list of operations to + perform on individual shared criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateSharedCriteriaResponse: + Response message for a shared + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a shared_criterion_service.MutateSharedCriteriaRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, shared_criterion_service.MutateSharedCriteriaRequest + ): + request = shared_criterion_service.MutateSharedCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_shared_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SharedCriterionServiceClient",) diff --git a/google/ads/googleads/v12/services/services/shared_criterion_service/transports/__init__.py b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/__init__.py new file mode 100644 index 000000000..1444fe523 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 SharedCriterionServiceTransport +from .grpc import SharedCriterionServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SharedCriterionServiceTransport]] +_transport_registry["grpc"] = SharedCriterionServiceGrpcTransport + +__all__ = ( + "SharedCriterionServiceTransport", + "SharedCriterionServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/shared_criterion_service/transports/base.py b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/base.py new file mode 100644 index 000000000..321caa22e --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import shared_criterion_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SharedCriterionServiceTransport(abc.ABC): + """Abstract transport class for SharedCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_shared_criteria: gapic_v1.method.wrap_method( + self.mutate_shared_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_shared_criteria( + self, + ) -> Callable[ + [shared_criterion_service.MutateSharedCriteriaRequest], + Union[ + shared_criterion_service.MutateSharedCriteriaResponse, + Awaitable[shared_criterion_service.MutateSharedCriteriaResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("SharedCriterionServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/shared_criterion_service/transports/grpc.py b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/grpc.py new file mode 100644 index 000000000..0276cdd58 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_criterion_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import shared_criterion_service +from .base import SharedCriterionServiceTransport, DEFAULT_CLIENT_INFO + + +class SharedCriterionServiceGrpcTransport(SharedCriterionServiceTransport): + """gRPC backend transport for SharedCriterionService. + + Service to manage shared criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_shared_criteria( + self, + ) -> Callable[ + [shared_criterion_service.MutateSharedCriteriaRequest], + shared_criterion_service.MutateSharedCriteriaResponse, + ]: + r"""Return a callable for the mutate shared criteria method over gRPC. + + Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedCriteriaRequest], + ~.MutateSharedCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_criteria" not in self._stubs: + self._stubs[ + "mutate_shared_criteria" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SharedCriterionService/MutateSharedCriteria", + request_serializer=shared_criterion_service.MutateSharedCriteriaRequest.serialize, + response_deserializer=shared_criterion_service.MutateSharedCriteriaResponse.deserialize, + ) + return self._stubs["mutate_shared_criteria"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("SharedCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/shared_set_service/__init__.py b/google/ads/googleads/v12/services/services/shared_set_service/__init__.py new file mode 100644 index 000000000..c43f1b2ba --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_set_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 SharedSetServiceClient + +__all__ = ("SharedSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/shared_set_service/client.py b/google/ads/googleads/v12/services/services/shared_set_service/client.py new file mode 100644 index 000000000..a6709cf98 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_set_service/client.py @@ -0,0 +1,488 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SharedSetServiceGrpcTransport + + +class SharedSetServiceClientMeta(type): + """Metaclass for the SharedSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SharedSetServiceTransport]] + _transport_registry["grpc"] = SharedSetServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[SharedSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SharedSetServiceClient(metaclass=SharedSetServiceClientMeta): + """Service to manage shared sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def shared_set_path(customer_id: str, shared_set_id: str,) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SharedSetServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SharedSetServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SharedSetServiceTransport): + # transport is a SharedSetServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_shared_sets( + self, + request: Union[shared_set_service.MutateSharedSetsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[shared_set_service.SharedSetOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> shared_set_service.MutateSharedSetsResponse: + r"""Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateSharedSetsRequest, dict]): + The request object. Request message for + [SharedSetService.MutateSharedSets][google.ads.googleads.v12.services.SharedSetService.MutateSharedSets]. + customer_id (str): + Required. The ID of the customer + whose shared sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.SharedSetOperation]): + Required. The list of operations to + perform on individual shared sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateSharedSetsResponse: + Response message for a shared set + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a shared_set_service.MutateSharedSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, shared_set_service.MutateSharedSetsRequest): + request = shared_set_service.MutateSharedSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SharedSetServiceClient",) diff --git a/google/ads/googleads/v12/services/services/shared_set_service/transports/__init__.py b/google/ads/googleads/v12/services/services/shared_set_service/transports/__init__.py new file mode 100644 index 000000000..1185bc3b4 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_set_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 SharedSetServiceTransport +from .grpc import SharedSetServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SharedSetServiceTransport]] +_transport_registry["grpc"] = SharedSetServiceGrpcTransport + +__all__ = ( + "SharedSetServiceTransport", + "SharedSetServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/shared_set_service/transports/base.py b/google/ads/googleads/v12/services/services/shared_set_service/transports/base.py new file mode 100644 index 000000000..1d8eeb518 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_set_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import shared_set_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SharedSetServiceTransport(abc.ABC): + """Abstract transport class for SharedSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_shared_sets: gapic_v1.method.wrap_method( + self.mutate_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_shared_sets( + self, + ) -> Callable[ + [shared_set_service.MutateSharedSetsRequest], + Union[ + shared_set_service.MutateSharedSetsResponse, + Awaitable[shared_set_service.MutateSharedSetsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("SharedSetServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/shared_set_service/transports/grpc.py b/google/ads/googleads/v12/services/services/shared_set_service/transports/grpc.py new file mode 100644 index 000000000..c8fe1a6d8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/shared_set_service/transports/grpc.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import shared_set_service +from .base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO + + +class SharedSetServiceGrpcTransport(SharedSetServiceTransport): + """gRPC backend transport for SharedSetService. + + Service to manage shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_shared_sets( + self, + ) -> Callable[ + [shared_set_service.MutateSharedSetsRequest], + shared_set_service.MutateSharedSetsResponse, + ]: + r"""Return a callable for the mutate shared sets method over gRPC. + + Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedSetsRequest], + ~.MutateSharedSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_sets" not in self._stubs: + self._stubs["mutate_shared_sets"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SharedSetService/MutateSharedSets", + request_serializer=shared_set_service.MutateSharedSetsRequest.serialize, + response_deserializer=shared_set_service.MutateSharedSetsResponse.deserialize, + ) + return self._stubs["mutate_shared_sets"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("SharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_setting_service/__init__.py b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/__init__.py new file mode 100644 index 000000000..bf1b79372 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 SmartCampaignSettingServiceClient + +__all__ = ("SmartCampaignSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_setting_service/client.py b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/client.py new file mode 100644 index 000000000..62de565d8 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/client.py @@ -0,0 +1,511 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SmartCampaignSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SmartCampaignSettingServiceGrpcTransport + + +class SmartCampaignSettingServiceClientMeta(type): + """Metaclass for the SmartCampaignSettingService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SmartCampaignSettingServiceTransport]] + _transport_registry["grpc"] = SmartCampaignSettingServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[SmartCampaignSettingServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SmartCampaignSettingServiceClient( + metaclass=SmartCampaignSettingServiceClientMeta +): + """Service to manage Smart campaign settings.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SmartCampaignSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSettingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, SmartCampaignSettingServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign setting service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SmartCampaignSettingServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SmartCampaignSettingServiceTransport): + # transport is a SmartCampaignSettingServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_smart_campaign_settings( + self, + request: Union[ + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + dict, + ] = None, + *, + customer_id: str = None, + operations: Sequence[ + smart_campaign_setting_service.SmartCampaignSettingOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> smart_campaign_setting_service.MutateSmartCampaignSettingsResponse: + r"""Updates Smart campaign settings for campaigns. + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateSmartCampaignSettingsRequest, dict]): + The request object. Request message for + [SmartCampaignSettingService.MutateSmartCampaignSetting][]. + customer_id (str): + Required. The ID of the customer + whose Smart campaign settings are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.SmartCampaignSettingOperation]): + Required. The list of operations to + perform on individual Smart campaign + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateSmartCampaignSettingsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a smart_campaign_setting_service.MutateSmartCampaignSettingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + ): + request = smart_campaign_setting_service.MutateSmartCampaignSettingsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_smart_campaign_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SmartCampaignSettingServiceClient",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/__init__.py b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/__init__.py new file mode 100644 index 000000000..4342cc365 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 SmartCampaignSettingServiceTransport +from .grpc import SmartCampaignSettingServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SmartCampaignSettingServiceTransport]] +_transport_registry["grpc"] = SmartCampaignSettingServiceGrpcTransport + +__all__ = ( + "SmartCampaignSettingServiceTransport", + "SmartCampaignSettingServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/base.py b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/base.py new file mode 100644 index 000000000..21b3cac35 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/base.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_setting_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SmartCampaignSettingServiceTransport(abc.ABC): + """Abstract transport class for SmartCampaignSettingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_smart_campaign_settings: gapic_v1.method.wrap_method( + self.mutate_smart_campaign_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_smart_campaign_settings( + self, + ) -> Callable[ + [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], + Union[ + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, + Awaitable[ + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("SmartCampaignSettingServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/grpc.py b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/grpc.py new file mode 100644 index 000000000..04b9e4419 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_setting_service/transports/grpc.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_setting_service, +) +from .base import SmartCampaignSettingServiceTransport, DEFAULT_CLIENT_INFO + + +class SmartCampaignSettingServiceGrpcTransport( + SmartCampaignSettingServiceTransport +): + """gRPC backend transport for SmartCampaignSettingService. + + Service to manage Smart campaign settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_smart_campaign_settings( + self, + ) -> Callable[ + [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, + ]: + r"""Return a callable for the mutate smart campaign settings method over gRPC. + + Updates Smart campaign settings for campaigns. + + Returns: + Callable[[~.MutateSmartCampaignSettingsRequest], + ~.MutateSmartCampaignSettingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_smart_campaign_settings" not in self._stubs: + self._stubs[ + "mutate_smart_campaign_settings" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SmartCampaignSettingService/MutateSmartCampaignSettings", + request_serializer=smart_campaign_setting_service.MutateSmartCampaignSettingsRequest.serialize, + response_deserializer=smart_campaign_setting_service.MutateSmartCampaignSettingsResponse.deserialize, + ) + return self._stubs["mutate_smart_campaign_settings"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("SmartCampaignSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/__init__.py b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/__init__.py new file mode 100644 index 000000000..6a64b2688 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 SmartCampaignSuggestServiceClient + +__all__ = ("SmartCampaignSuggestServiceClient",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/client.py b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/client.py new file mode 100644 index 000000000..c61ce3512 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/client.py @@ -0,0 +1,610 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_suggest_service, +) +from .transports.base import ( + SmartCampaignSuggestServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SmartCampaignSuggestServiceGrpcTransport + + +class SmartCampaignSuggestServiceClientMeta(type): + """Metaclass for the SmartCampaignSuggestService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SmartCampaignSuggestServiceTransport]] + _transport_registry["grpc"] = SmartCampaignSuggestServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[SmartCampaignSuggestServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SmartCampaignSuggestServiceClient( + metaclass=SmartCampaignSuggestServiceClientMeta +): + """Service to get suggestions for Smart Campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SmartCampaignSuggestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSuggestServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def campaign_path(customer_id: str, campaign_id: str,) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, SmartCampaignSuggestServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign suggest service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SmartCampaignSuggestServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SmartCampaignSuggestServiceTransport): + # transport is a SmartCampaignSuggestServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def suggest_smart_campaign_budget_options( + self, + request: Union[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + dict, + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse: + r"""Returns BudgetOption suggestions. + + Args: + request (Union[google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgets][]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgets][]. + Depending on whether the system could suggest the + options, either all of the options or none of them + might be returned. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + ): + request = smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_smart_campaign_budget_options + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def suggest_smart_campaign_ad( + self, + request: Union[ + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> smart_campaign_suggest_service.SuggestSmartCampaignAdResponse: + r"""Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Args: + request (Union[google.ads.googleads.v12.services.types.SuggestSmartCampaignAdRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.SuggestSmartCampaignAdResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a smart_campaign_suggest_service.SuggestSmartCampaignAdRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, + ): + request = smart_campaign_suggest_service.SuggestSmartCampaignAdRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_smart_campaign_ad + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + def suggest_keyword_themes( + self, + request: Union[ + smart_campaign_suggest_service.SuggestKeywordThemesRequest, dict + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> smart_campaign_suggest_service.SuggestKeywordThemesResponse: + r"""Suggests keyword themes to advertise on. + + Args: + request (Union[google.ads.googleads.v12.services.types.SuggestKeywordThemesRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.SuggestKeywordThemesResponse: + Response message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a smart_campaign_suggest_service.SuggestKeywordThemesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, smart_campaign_suggest_service.SuggestKeywordThemesRequest + ): + request = smart_campaign_suggest_service.SuggestKeywordThemesRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_keyword_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SmartCampaignSuggestServiceClient",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/__init__.py b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/__init__.py new file mode 100644 index 000000000..3f81aa74a --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 SmartCampaignSuggestServiceTransport +from .grpc import SmartCampaignSuggestServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SmartCampaignSuggestServiceTransport]] +_transport_registry["grpc"] = SmartCampaignSuggestServiceGrpcTransport + +__all__ = ( + "SmartCampaignSuggestServiceTransport", + "SmartCampaignSuggestServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/base.py b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/base.py new file mode 100644 index 000000000..dffb72753 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/base.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_suggest_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SmartCampaignSuggestServiceTransport(abc.ABC): + """Abstract transport class for SmartCampaignSuggestService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_smart_campaign_budget_options: gapic_v1.method.wrap_method( + self.suggest_smart_campaign_budget_options, + default_timeout=None, + client_info=client_info, + ), + self.suggest_smart_campaign_ad: gapic_v1.method.wrap_method( + self.suggest_smart_campaign_ad, + default_timeout=None, + client_info=client_info, + ), + self.suggest_keyword_themes: gapic_v1.method.wrap_method( + self.suggest_keyword_themes, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_smart_campaign_budget_options( + self, + ) -> Callable[ + [ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest + ], + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def suggest_smart_campaign_ad( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def suggest_keyword_themes( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestKeywordThemesRequest], + Union[ + smart_campaign_suggest_service.SuggestKeywordThemesResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestKeywordThemesResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("SmartCampaignSuggestServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/grpc.py b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/grpc.py new file mode 100644 index 000000000..15c102632 --- /dev/null +++ b/google/ads/googleads/v12/services/services/smart_campaign_suggest_service/transports/grpc.py @@ -0,0 +1,341 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + smart_campaign_suggest_service, +) +from .base import SmartCampaignSuggestServiceTransport, DEFAULT_CLIENT_INFO + + +class SmartCampaignSuggestServiceGrpcTransport( + SmartCampaignSuggestServiceTransport +): + """gRPC backend transport for SmartCampaignSuggestService. + + Service to get suggestions for Smart Campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def suggest_smart_campaign_budget_options( + self, + ) -> Callable[ + [ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest + ], + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, + ]: + r"""Return a callable for the suggest smart campaign budget + options method over gRPC. + + Returns BudgetOption suggestions. + + Returns: + Callable[[~.SuggestSmartCampaignBudgetOptionsRequest], + ~.SuggestSmartCampaignBudgetOptionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_budget_options" not in self._stubs: + self._stubs[ + "suggest_smart_campaign_budget_options" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SmartCampaignSuggestService/SuggestSmartCampaignBudgetOptions", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse.deserialize, + ) + return self._stubs["suggest_smart_campaign_budget_options"] + + @property + def suggest_smart_campaign_ad( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, + ]: + r"""Return a callable for the suggest smart campaign ad method over gRPC. + + Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Returns: + Callable[[~.SuggestSmartCampaignAdRequest], + ~.SuggestSmartCampaignAdResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_ad" not in self._stubs: + self._stubs[ + "suggest_smart_campaign_ad" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SmartCampaignSuggestService/SuggestSmartCampaignAd", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignAdRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignAdResponse.deserialize, + ) + return self._stubs["suggest_smart_campaign_ad"] + + @property + def suggest_keyword_themes( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestKeywordThemesRequest], + smart_campaign_suggest_service.SuggestKeywordThemesResponse, + ]: + r"""Return a callable for the suggest keyword themes method over gRPC. + + Suggests keyword themes to advertise on. + + Returns: + Callable[[~.SuggestKeywordThemesRequest], + ~.SuggestKeywordThemesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_themes" not in self._stubs: + self._stubs[ + "suggest_keyword_themes" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.SmartCampaignSuggestService/SuggestKeywordThemes", + request_serializer=smart_campaign_suggest_service.SuggestKeywordThemesRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestKeywordThemesResponse.deserialize, + ) + return self._stubs["suggest_keyword_themes"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("SmartCampaignSuggestServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/__init__.py b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/__init__.py new file mode 100644 index 000000000..8b5caeafa --- /dev/null +++ b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ThirdPartyAppAnalyticsLinkServiceClient + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/client.py b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/client.py new file mode 100644 index 000000000..306175962 --- /dev/null +++ b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/client.py @@ -0,0 +1,471 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import ( + third_party_app_analytics_link_service, +) +from .transports.base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ThirdPartyAppAnalyticsLinkServiceGrpcTransport + + +class ThirdPartyAppAnalyticsLinkServiceClientMeta(type): + """Metaclass for the ThirdPartyAppAnalyticsLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ThirdPartyAppAnalyticsLinkServiceTransport]] + _transport_registry["grpc"] = ThirdPartyAppAnalyticsLinkServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ThirdPartyAppAnalyticsLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ThirdPartyAppAnalyticsLinkServiceClient( + metaclass=ThirdPartyAppAnalyticsLinkServiceClientMeta +): + """This service allows management of links between Google Ads + and third party app analytics. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ThirdPartyAppAnalyticsLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ThirdPartyAppAnalyticsLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def third_party_app_analytics_link_path( + customer_id: str, customer_link_id: str, + ) -> str: + """Returns a fully-qualified third_party_app_analytics_link string.""" + return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( + customer_id=customer_id, customer_link_id=customer_link_id, + ) + + @staticmethod + def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: + """Parses a third_party_app_analytics_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[ + str, ThirdPartyAppAnalyticsLinkServiceTransport, None + ] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the third party app analytics link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ThirdPartyAppAnalyticsLinkServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ThirdPartyAppAnalyticsLinkServiceTransport): + # transport is a ThirdPartyAppAnalyticsLinkServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def regenerate_shareable_link_id( + self, + request: Union[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + dict, + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse: + r"""Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.RegenerateShareableLinkIdRequest, dict]): + The request object. Request message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v12.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.RegenerateShareableLinkIdResponse: + Response message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v12.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + ): + request = third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.regenerate_shareable_link_id + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceClient",) diff --git a/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/__init__.py b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/__init__.py new file mode 100644 index 000000000..10da1176b --- /dev/null +++ b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 ThirdPartyAppAnalyticsLinkServiceTransport +from .grpc import ThirdPartyAppAnalyticsLinkServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ThirdPartyAppAnalyticsLinkServiceTransport]] +_transport_registry["grpc"] = ThirdPartyAppAnalyticsLinkServiceGrpcTransport + +__all__ = ( + "ThirdPartyAppAnalyticsLinkServiceTransport", + "ThirdPartyAppAnalyticsLinkServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/base.py b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/base.py new file mode 100644 index 000000000..c88de8421 --- /dev/null +++ b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/base.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import ( + third_party_app_analytics_link_service, +) + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ThirdPartyAppAnalyticsLinkServiceTransport(abc.ABC): + """Abstract transport class for ThirdPartyAppAnalyticsLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.regenerate_shareable_link_id: gapic_v1.method.wrap_method( + self.regenerate_shareable_link_id, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def regenerate_shareable_link_id( + self, + ) -> Callable[ + [ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest + ], + Union[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, + Awaitable[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse + ], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/grpc.py b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/grpc.py new file mode 100644 index 000000000..c3bdbe586 --- /dev/null +++ b/google/ads/googleads/v12/services/services/third_party_app_analytics_link_service/transports/grpc.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import ( + third_party_app_analytics_link_service, +) +from .base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) + + +class ThirdPartyAppAnalyticsLinkServiceGrpcTransport( + ThirdPartyAppAnalyticsLinkServiceTransport +): + """gRPC backend transport for ThirdPartyAppAnalyticsLinkService. + + This service allows management of links between Google Ads + and third party app analytics. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def regenerate_shareable_link_id( + self, + ) -> Callable[ + [ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest + ], + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, + ]: + r"""Return a callable for the regenerate shareable link id method over gRPC. + + Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RegenerateShareableLinkIdRequest], + ~.RegenerateShareableLinkIdResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "regenerate_shareable_link_id" not in self._stubs: + self._stubs[ + "regenerate_shareable_link_id" + ] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.ThirdPartyAppAnalyticsLinkService/RegenerateShareableLinkId", + request_serializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest.serialize, + response_deserializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse.deserialize, + ) + return self._stubs["regenerate_shareable_link_id"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/user_data_service/__init__.py b/google/ads/googleads/v12/services/services/user_data_service/__init__.py new file mode 100644 index 000000000..8ba2fca31 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_data_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 UserDataServiceClient + +__all__ = ("UserDataServiceClient",) diff --git a/google/ads/googleads/v12/services/services/user_data_service/client.py b/google/ads/googleads/v12/services/services/user_data_service/client.py new file mode 100644 index 000000000..91a39a39c --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_data_service/client.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import user_data_service +from .transports.base import UserDataServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserDataServiceGrpcTransport + + +class UserDataServiceClientMeta(type): + """Metaclass for the UserDataService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[UserDataServiceTransport]] + _transport_registry["grpc"] = UserDataServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[UserDataServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserDataServiceClient(metaclass=UserDataServiceClientMeta): + """Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserDataServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserDataServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserDataServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user data service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, UserDataServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, UserDataServiceTransport): + # transport is a UserDataServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def upload_user_data( + self, + request: Union[user_data_service.UploadUserDataRequest, dict] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_data_service.UploadUserDataResponse: + r"""Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.UploadUserDataRequest, dict]): + The request object. Request message for + [UserDataService.UploadUserData][google.ads.googleads.v12.services.UserDataService.UploadUserData] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.UploadUserDataResponse: + Response message for [UserDataService.UploadUserData][google.ads.googleads.v12.services.UserDataService.UploadUserData] + Uploads made through this service will not be visible + under the 'Segment members' section for the Customer + Match List in the Google Ads UI. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_data_service.UploadUserDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_data_service.UploadUserDataRequest): + request = user_data_service.UploadUserDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.upload_user_data] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("UserDataServiceClient",) diff --git a/google/ads/googleads/v12/services/services/user_data_service/transports/__init__.py b/google/ads/googleads/v12/services/services/user_data_service/transports/__init__.py new file mode 100644 index 000000000..94432cef3 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_data_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 UserDataServiceTransport +from .grpc import UserDataServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[UserDataServiceTransport]] +_transport_registry["grpc"] = UserDataServiceGrpcTransport + +__all__ = ( + "UserDataServiceTransport", + "UserDataServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/user_data_service/transports/base.py b/google/ads/googleads/v12/services/services/user_data_service/transports/base.py new file mode 100644 index 000000000..d18e06a61 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_data_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import user_data_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class UserDataServiceTransport(abc.ABC): + """Abstract transport class for UserDataService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_user_data: gapic_v1.method.wrap_method( + self.upload_user_data, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_user_data( + self, + ) -> Callable[ + [user_data_service.UploadUserDataRequest], + Union[ + user_data_service.UploadUserDataResponse, + Awaitable[user_data_service.UploadUserDataResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("UserDataServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/user_data_service/transports/grpc.py b/google/ads/googleads/v12/services/services/user_data_service/transports/grpc.py new file mode 100644 index 000000000..0191d4312 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_data_service/transports/grpc.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import user_data_service +from .base import UserDataServiceTransport, DEFAULT_CLIENT_INFO + + +class UserDataServiceGrpcTransport(UserDataServiceTransport): + """gRPC backend transport for UserDataService. + + Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def upload_user_data( + self, + ) -> Callable[ + [user_data_service.UploadUserDataRequest], + user_data_service.UploadUserDataResponse, + ]: + r"""Return a callable for the upload user data method over gRPC. + + Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Returns: + Callable[[~.UploadUserDataRequest], + ~.UploadUserDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_user_data" not in self._stubs: + self._stubs["upload_user_data"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.UserDataService/UploadUserData", + request_serializer=user_data_service.UploadUserDataRequest.serialize, + response_deserializer=user_data_service.UploadUserDataResponse.deserialize, + ) + return self._stubs["upload_user_data"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("UserDataServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/services/user_list_service/__init__.py b/google/ads/googleads/v12/services/services/user_list_service/__init__.py new file mode 100644 index 000000000..d7b0c7527 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_list_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 UserListServiceClient + +__all__ = ("UserListServiceClient",) diff --git a/google/ads/googleads/v12/services/services/user_list_service/client.py b/google/ads/googleads/v12/services/services/user_list_service/client.py new file mode 100644 index 000000000..733e9c090 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_list_service/client.py @@ -0,0 +1,486 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF 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 os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.ads.googleads.v12.services.types import user_list_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import UserListServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserListServiceGrpcTransport + + +class UserListServiceClientMeta(type): + """Metaclass for the UserListService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[UserListServiceTransport]] + _transport_registry["grpc"] = UserListServiceGrpcTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[UserListServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserListServiceClient(metaclass=UserListServiceClientMeta): + """Service to manage user lists.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserListServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserListServiceTransport: The transport used by the client + instance. + """ + return self._transport + + def __enter__(self): + 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() + + @staticmethod + def user_list_path(customer_id: str, user_list_id: str,) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserListServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user list service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, UserListServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if is_mtls + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, UserListServiceTransport): + # transport is a UserListServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def mutate_user_lists( + self, + request: Union[user_list_service.MutateUserListsRequest, dict] = None, + *, + customer_id: str = None, + operations: Sequence[user_list_service.UserListOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_list_service.MutateUserListsResponse: + r"""Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Args: + request (Union[google.ads.googleads.v12.services.types.MutateUserListsRequest, dict]): + The request object. Request message for + [UserListService.MutateUserLists][google.ads.googleads.v12.services.UserListService.MutateUserLists]. + customer_id (str): + Required. The ID of the customer + whose user lists are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (Sequence[google.ads.googleads.v12.services.types.UserListOperation]): + Required. The list of operations to + perform on individual user lists. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.ads.googleads.v12.services.types.MutateUserListsResponse: + Response message for user list + mutate. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([customer_id, operations]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a user_list_service.MutateUserListsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_list_service.MutateUserListsRequest): + request = user_list_service.MutateUserListsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_user_lists + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata, + ) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("UserListServiceClient",) diff --git a/google/ads/googleads/v12/services/services/user_list_service/transports/__init__.py b/google/ads/googleads/v12/services/services/user_list_service/transports/__init__.py new file mode 100644 index 000000000..6a2a9616c --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_list_service/transports/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 UserListServiceTransport +from .grpc import UserListServiceGrpcTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[UserListServiceTransport]] +_transport_registry["grpc"] = UserListServiceGrpcTransport + +__all__ = ( + "UserListServiceTransport", + "UserListServiceGrpcTransport", +) diff --git a/google/ads/googleads/v12/services/services/user_list_service/transports/base.py b/google/ads/googleads/v12/services/services/user_list_service/transports/base.py new file mode 100644 index 000000000..9aac90e30 --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_list_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.ads.googleads.v12.services.types import user_list_service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-ads",).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class UserListServiceTransport(abc.ABC): + """Abstract transport class for UserListService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # 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: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_user_lists: gapic_v1.method.wrap_method( + self.mutate_user_lists, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_user_lists( + self, + ) -> Callable[ + [user_list_service.MutateUserListsRequest], + Union[ + user_list_service.MutateUserListsResponse, + Awaitable[user_list_service.MutateUserListsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("UserListServiceTransport",) diff --git a/google/ads/googleads/v12/services/services/user_list_service/transports/grpc.py b/google/ads/googleads/v12/services/services/user_list_service/transports/grpc.py new file mode 100644 index 000000000..4f1d5243d --- /dev/null +++ b/google/ads/googleads/v12/services/services/user_list_service/transports/grpc.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.ads.googleads.v12.services.types import user_list_service +from .base import UserListServiceTransport, DEFAULT_CLIENT_INFO + + +class UserListServiceGrpcTransport(UserListServiceTransport): + """gRPC backend transport for UserListService. + + Service to manage user lists. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def mutate_user_lists( + self, + ) -> Callable[ + [user_list_service.MutateUserListsRequest], + user_list_service.MutateUserListsResponse, + ]: + r"""Return a callable for the mutate user lists method over gRPC. + + Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Returns: + Callable[[~.MutateUserListsRequest], + ~.MutateUserListsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_user_lists" not in self._stubs: + self._stubs["mutate_user_lists"] = self.grpc_channel.unary_unary( + "/google.ads.googleads.v12.services.UserListService/MutateUserLists", + request_serializer=user_list_service.MutateUserListsRequest.serialize, + response_deserializer=user_list_service.MutateUserListsResponse.deserialize, + ) + return self._stubs["mutate_user_lists"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("UserListServiceGrpcTransport",) diff --git a/google/ads/googleads/v12/services/types/__init__.py b/google/ads/googleads/v12/services/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/services/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/google/ads/googleads/v12/services/types/account_budget_proposal_service.py b/google/ads/googleads/v12/services/types/account_budget_proposal_service.py new file mode 100644 index 000000000..756883eb9 --- /dev/null +++ b/google/ads/googleads/v12/services/types/account_budget_proposal_service.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import account_budget_proposal +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAccountBudgetProposalRequest", + "AccountBudgetProposalOperation", + "MutateAccountBudgetProposalResponse", + "MutateAccountBudgetProposalResult", + }, +) + + +class MutateAccountBudgetProposalRequest(proto.Message): + r"""Request message for + [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v12.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + operation (google.ads.googleads.v12.services.types.AccountBudgetProposalOperation): + Required. The operation to perform on an + individual account-level budget proposal. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="AccountBudgetProposalOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class AccountBudgetProposalOperation(proto.Message): + r"""A single operation to propose the creation of a new + account-level budget or edit/end/remove an existing one. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which budget fields + are modified. While budgets may be modified, + proposals that propose such modifications are + final. Therefore, update operations are not + supported for proposals. + Proposals that modify budgets have the 'update' + proposal type. Specifying a mask for any other + proposal type is considered an error. + create (google.ads.googleads.v12.resources.types.AccountBudgetProposal): + Create operation: A new proposal to create a + new budget, edit an existing budget, end an + actively running budget, or remove an approved + budget scheduled to start in the future. + No resource name is expected for the new + proposal. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed proposal + is expected, in this format: + + ``customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}`` + A request may be cancelled iff it is pending. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=account_budget_proposal.AccountBudgetProposal, + ) + remove = proto.Field(proto.STRING, number=1, oneof="operation",) + + +class MutateAccountBudgetProposalResponse(proto.Message): + r"""Response message for account-level budget mutate operations. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateAccountBudgetProposalResult): + The result of the mutate. + """ + + result = proto.Field( + proto.MESSAGE, number=2, message="MutateAccountBudgetProposalResult", + ) + + +class MutateAccountBudgetProposalResult(proto.Message): + r"""The result for the account budget proposal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/account_link_service.py b/google/ads/googleads/v12/services/types/account_link_service.py new file mode 100644 index 000000000..0cc63ba7b --- /dev/null +++ b/google/ads/googleads/v12/services/types/account_link_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + account_link as gagr_account_link, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "CreateAccountLinkRequest", + "CreateAccountLinkResponse", + "MutateAccountLinkRequest", + "AccountLinkOperation", + "MutateAccountLinkResponse", + "MutateAccountLinkResult", + }, +) + + +class CreateAccountLinkRequest(proto.Message): + r"""Request message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v12.services.AccountLinkService.CreateAccountLink]. + + Attributes: + customer_id (str): + Required. The ID of the customer for which + the account link is created. + account_link (google.ads.googleads.v12.resources.types.AccountLink): + Required. The account link to be created. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + account_link = proto.Field( + proto.MESSAGE, number=2, message=gagr_account_link.AccountLink, + ) + + +class CreateAccountLinkResponse(proto.Message): + r"""Response message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v12.services.AccountLinkService.CreateAccountLink]. + + Attributes: + resource_name (str): + Returned for successful operations. Resource + name of the account link. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class MutateAccountLinkRequest(proto.Message): + r"""Request message for + [AccountLinkService.MutateAccountLink][google.ads.googleads.v12.services.AccountLinkService.MutateAccountLink]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + modified. + operation (google.ads.googleads.v12.services.types.AccountLinkOperation): + Required. The operation to perform on the + link. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="AccountLinkOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AccountLinkOperation(proto.Message): + r"""A single update on an account link. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.AccountLink): + Update operation: The account link is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the account link to + remove is expected, in this format: + + ``customers/{customer_id}/accountLinks/{account_link_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_account_link.AccountLink, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAccountLinkResponse(proto.Message): + r"""Response message for account link mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateAccountLinkResult): + Result for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + result = proto.Field( + proto.MESSAGE, number=1, message="MutateAccountLinkResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAccountLinkResult(proto.Message): + r"""The result for the account link mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_ad_label_service.py b/google/ads/googleads/v12/services/types/ad_group_ad_label_service.py new file mode 100644 index 000000000..f5d9f161e --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_ad_label_service.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ad_group_ad_label +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupAdLabelsRequest", + "AdGroupAdLabelOperation", + "MutateAdGroupAdLabelsResponse", + "MutateAdGroupAdLabelResult", + }, +) + + +class MutateAdGroupAdLabelsRequest(proto.Message): + r"""Request message for + [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v12.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose ad group + ad labels are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAdLabelOperation]): + Required. The list of operations to perform + on ad group ad labels. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupAdLabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AdGroupAdLabelOperation(proto.Message): + r"""A single operation (create, remove) on an ad group ad label. + + 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: + create (google.ads.googleads.v12.resources.types.AdGroupAdLabel): + Create operation: No resource name is + expected for the new ad group ad label. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the ad group ad label + being removed, in this format: + + ``customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=ad_group_ad_label.AdGroupAdLabel, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupAdLabelsResponse(proto.Message): + r"""Response message for an ad group ad labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupAdLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupAdLabelResult", + ) + + +class MutateAdGroupAdLabelResult(proto.Message): + r"""The result for an ad group ad label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_ad_service.py b/google/ads/googleads/v12/services/types/ad_group_ad_service.py new file mode 100644 index 000000000..36f0f3662 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_ad_service.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_ad as gagr_ad_group_ad, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupAdsRequest", + "AdGroupAdOperation", + "MutateAdGroupAdsResponse", + "MutateAdGroupAdResult", + }, +) + + +class MutateAdGroupAdsRequest(proto.Message): + r"""Request message for + [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v12.services.AdGroupAdService.MutateAdGroupAds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ads + are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAdOperation]): + Required. The list of operations to perform + on individual ads. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupAdOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupAdOperation(proto.Message): + r"""A single operation (create, update, remove) on an ad group + ad. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + policy_validation_parameter (google.ads.googleads.v12.common.types.PolicyValidationParameter): + Configuration for how policies are validated. + create (google.ads.googleads.v12.resources.types.AdGroupAd): + Create operation: No resource name is + expected for the new ad. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupAd): + Update operation: The ad is expected to have + a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad is + expected, in this format: + + ``customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + policy_validation_parameter = proto.Field( + proto.MESSAGE, number=5, message=policy.PolicyValidationParameter, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_ad.AdGroupAd, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group_ad.AdGroupAd, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupAdsResponse(proto.Message): + r"""Response message for an ad group ad mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupAdResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupAdResult", + ) + + +class MutateAdGroupAdResult(proto.Message): + r"""The result for the ad mutate. + + Attributes: + resource_name (str): + The resource name returned for successful + operations. + ad_group_ad (google.ads.googleads.v12.resources.types.AdGroupAd): + The mutated ad group ad with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_ad = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_group_ad.AdGroupAd, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_asset_service.py b/google/ads/googleads/v12/services/types/ad_group_asset_service.py new file mode 100644 index 000000000..11d8e3798 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_asset_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_asset as gagr_ad_group_asset, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupAssetsRequest", + "AdGroupAssetOperation", + "MutateAdGroupAssetsResponse", + "MutateAdGroupAssetResult", + }, +) + + +class MutateAdGroupAssetsRequest(proto.Message): + r"""Request message for + [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v12.services.AdGroupAssetService.MutateAdGroupAssets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group assets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAssetOperation]): + Required. The list of operations to perform + on individual ad group assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupAssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupAssetOperation(proto.Message): + r"""A single operation (create, update, remove) on an ad group + asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AdGroupAsset): + Create operation: No resource name is + expected for the new ad group asset. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupAsset): + Update operation: The ad group asset is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + asset is expected, in this format: + + ``customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_asset.AdGroupAsset, + ) + update = proto.Field( + proto.MESSAGE, + number=3, + oneof="operation", + message=gagr_ad_group_asset.AdGroupAsset, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupAssetsResponse(proto.Message): + r"""Response message for an ad group asset mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupAssetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupAssetResult", + ) + + +class MutateAdGroupAssetResult(proto.Message): + r"""The result for the ad group asset mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_asset (google.ads.googleads.v12.resources.types.AdGroupAsset): + The mutated ad group asset with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_asset = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_group_asset.AdGroupAsset, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_asset_set_service.py b/google/ads/googleads/v12/services/types/ad_group_asset_set_service.py new file mode 100644 index 000000000..216975e19 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_asset_set_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_asset_set as gagr_ad_group_asset_set, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupAssetSetsRequest", + "AdGroupAssetSetOperation", + "MutateAdGroupAssetSetsResponse", + "MutateAdGroupAssetSetResult", + }, +) + + +class MutateAdGroupAssetSetsRequest(proto.Message): + r"""Request message for + [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v12.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group asset sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupAssetSetOperation]): + Required. The list of operations to perform + on individual ad group asset sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupAssetSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupAssetSetOperation(proto.Message): + r"""A single operation (create, remove) on an ad group asset set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.AdGroupAssetSet): + Create operation: No resource name is + expected for the new ad group asset set. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + asset set is expected, in this format: + ``customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_asset_set.AdGroupAssetSet, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupAssetSetsResponse(proto.Message): + r"""Response message for an ad group asset set mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupAssetSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (e.g. auth errors), we return an RPC + level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAdGroupAssetSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAdGroupAssetSetResult(proto.Message): + r"""The result for the ad group asset set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_asset_set (google.ads.googleads.v12.resources.types.AdGroupAssetSet): + The mutated ad group asset set with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_asset_set = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_asset_set.AdGroupAssetSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_bid_modifier_service.py b/google/ads/googleads/v12/services/types/ad_group_bid_modifier_service.py new file mode 100644 index 000000000..ac25fa370 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_bid_modifier_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_bid_modifier as gagr_ad_group_bid_modifier, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupBidModifiersRequest", + "AdGroupBidModifierOperation", + "MutateAdGroupBidModifiersResponse", + "MutateAdGroupBidModifierResult", + }, +) + + +class MutateAdGroupBidModifiersRequest(proto.Message): + r"""Request message for + [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v12.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. + + Attributes: + customer_id (str): + Required. ID of the customer whose ad group + bid modifiers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupBidModifierOperation]): + Required. The list of operations to perform + on individual ad group bid modifiers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupBidModifierOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupBidModifierOperation(proto.Message): + r"""A single operation (create, remove, update) on an ad group + bid modifier. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AdGroupBidModifier): + Create operation: No resource name is + expected for the new ad group bid modifier. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupBidModifier): + Update operation: The ad group bid modifier + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + bid modifier is expected, in this format: + + ``customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_bid_modifier.AdGroupBidModifier, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group_bid_modifier.AdGroupBidModifier, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupBidModifiersResponse(proto.Message): + r"""Response message for ad group bid modifiers mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupBidModifierResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupBidModifierResult", + ) + + +class MutateAdGroupBidModifierResult(proto.Message): + r"""The result for the criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_bid_modifier (google.ads.googleads.v12.resources.types.AdGroupBidModifier): + The mutated ad group bid modifier with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_bid_modifier = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_bid_modifier.AdGroupBidModifier, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_criterion_customizer_service.py b/google/ads/googleads/v12/services/types/ad_group_criterion_customizer_service.py new file mode 100644 index 000000000..a232e827f --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_criterion_customizer_service.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion_customizer as gagr_ad_group_criterion_customizer, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupCriterionCustomizersRequest", + "AdGroupCriterionCustomizerOperation", + "MutateAdGroupCriterionCustomizersResponse", + "MutateAdGroupCriterionCustomizerResult", + }, +) + + +class MutateAdGroupCriterionCustomizersRequest(proto.Message): + r"""Request message for + [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v12.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group criterion customizers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionCustomizerOperation]): + Required. The list of operations to perform + on individual ad group criterion customizers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupCriterionCustomizerOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupCriterionCustomizerOperation(proto.Message): + r"""A single operation (create, remove) on an customizer + attribute. + + 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: + create (google.ads.googleads.v12.resources.types.AdGroupCriterionCustomizer): + Create operation: No resource name is + expected for the new ad group criterion + customizer. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + criterion customizer is expected, in this format: + + ``customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_criterion_customizer.AdGroupCriterionCustomizer, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupCriterionCustomizersResponse(proto.Message): + r"""Response message for an ad group criterion customizer mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupCriterionCustomizerResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="MutateAdGroupCriterionCustomizerResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAdGroupCriterionCustomizerResult(proto.Message): + r"""The result for the ad group criterion customizer mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_criterion_customizer (google.ads.googleads.v12.resources.types.AdGroupCriterionCustomizer): + The mutated AdGroupCriterionCustomizer with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_criterion_customizer = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_criterion_customizer.AdGroupCriterionCustomizer, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_criterion_label_service.py b/google/ads/googleads/v12/services/types/ad_group_criterion_label_service.py new file mode 100644 index 000000000..99faacc5c --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_criterion_label_service.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ad_group_criterion_label +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupCriterionLabelsRequest", + "AdGroupCriterionLabelOperation", + "MutateAdGroupCriterionLabelsResponse", + "MutateAdGroupCriterionLabelResult", + }, +) + + +class MutateAdGroupCriterionLabelsRequest(proto.Message): + r"""Request message for + [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v12.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose ad group + criterion labels are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionLabelOperation]): + Required. The list of operations to perform + on ad group criterion labels. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupCriterionLabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AdGroupCriterionLabelOperation(proto.Message): + r"""A single operation (create, remove) on an ad group criterion + label. + + 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: + create (google.ads.googleads.v12.resources.types.AdGroupCriterionLabel): + Create operation: No resource name is + expected for the new ad group label. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the ad group criterion + label being removed, in this format: + + ``customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=ad_group_criterion_label.AdGroupCriterionLabel, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupCriterionLabelsResponse(proto.Message): + r"""Response message for an ad group criterion labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupCriterionLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupCriterionLabelResult", + ) + + +class MutateAdGroupCriterionLabelResult(proto.Message): + r"""The result for an ad group criterion label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_criterion_service.py b/google/ads/googleads/v12/services/types/ad_group_criterion_service.py new file mode 100644 index 000000000..fef0e095c --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_criterion_service.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion as gagr_ad_group_criterion, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupCriteriaRequest", + "AdGroupCriterionOperation", + "MutateAdGroupCriteriaResponse", + "MutateAdGroupCriterionResult", + }, +) + + +class MutateAdGroupCriteriaRequest(proto.Message): + r"""Request message for + [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v12.services.AdGroupCriterionService.MutateAdGroupCriteria]. + + Attributes: + customer_id (str): + Required. ID of the customer whose criteria + are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCriterionOperation]): + Required. The list of operations to perform + on individual criteria. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupCriterionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupCriterionOperation(proto.Message): + r"""A single operation (create, remove, update) on an ad group + criterion. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + exempt_policy_violation_keys (Sequence[google.ads.googleads.v12.common.types.PolicyViolationKey]): + The list of policy violation keys that should not cause a + PolicyViolationError to be reported. Not all policy + violations are exemptable, refer to the is_exemptible field + in the returned PolicyViolationError. + + Resources violating these polices will be saved, but will + not be eligible to serve. They may begin serving at a later + time due to a change in policies, re-review of the resource, + or a change in advertiser certificates. + create (google.ads.googleads.v12.resources.types.AdGroupCriterion): + Create operation: No resource name is + expected for the new criterion. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupCriterion): + Update operation: The criterion is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed criterion + is expected, in this format: + + ``customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + exempt_policy_violation_keys = proto.RepeatedField( + proto.MESSAGE, number=5, message=policy.PolicyViolationKey, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_criterion.AdGroupCriterion, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group_criterion.AdGroupCriterion, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupCriteriaResponse(proto.Message): + r"""Response message for an ad group criterion mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupCriterionResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupCriterionResult", + ) + + +class MutateAdGroupCriterionResult(proto.Message): + r"""The result for the criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_criterion (google.ads.googleads.v12.resources.types.AdGroupCriterion): + The mutated ad group criterion with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_criterion = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_criterion.AdGroupCriterion, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_customizer_service.py b/google/ads/googleads/v12/services/types/ad_group_customizer_service.py new file mode 100644 index 000000000..f462bc44f --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_customizer_service.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_customizer as gagr_ad_group_customizer, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupCustomizersRequest", + "AdGroupCustomizerOperation", + "MutateAdGroupCustomizersResponse", + "MutateAdGroupCustomizerResult", + }, +) + + +class MutateAdGroupCustomizersRequest(proto.Message): + r"""Request message for + [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v12.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group customizers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupCustomizerOperation]): + Required. The list of operations to perform + on individual ad group customizers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupCustomizerOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupCustomizerOperation(proto.Message): + r"""A single operation (create, remove) on an customizer + attribute. + + 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: + create (google.ads.googleads.v12.resources.types.AdGroupCustomizer): + Create operation: No resource name is + expected for the new ad group customizer + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + customizer is expected, in this format: + ``customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_customizer.AdGroupCustomizer, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupCustomizersResponse(proto.Message): + r"""Response message for an ad group customizer mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupCustomizerResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAdGroupCustomizerResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAdGroupCustomizerResult(proto.Message): + r"""The result for the ad group customizer mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_customizer (google.ads.googleads.v12.resources.types.AdGroupCustomizer): + The mutated AdGroupCustomizer with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_customizer = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_customizer.AdGroupCustomizer, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_extension_setting_service.py b/google/ads/googleads/v12/services/types/ad_group_extension_setting_service.py new file mode 100644 index 000000000..0b1358a5d --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_extension_setting_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_extension_setting as gagr_ad_group_extension_setting, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupExtensionSettingsRequest", + "AdGroupExtensionSettingOperation", + "MutateAdGroupExtensionSettingsResponse", + "MutateAdGroupExtensionSettingResult", + }, +) + + +class MutateAdGroupExtensionSettingsRequest(proto.Message): + r"""Request message for + [AdGroupExtensionSettingService.MutateAdGroupExtensionSettings][google.ads.googleads.v12.services.AdGroupExtensionSettingService.MutateAdGroupExtensionSettings]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group extension settings are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupExtensionSettingOperation]): + Required. The list of operations to perform + on individual ad group extension settings. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupExtensionSettingOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AdGroupExtensionSettingOperation(proto.Message): + r"""A single operation (create, update, remove) on an ad group + extension setting. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + create (google.ads.googleads.v12.resources.types.AdGroupExtensionSetting): + Create operation: No resource name is + expected for the new ad group extension setting. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupExtensionSetting): + Update operation: The ad group extension + setting is expected to have a valid resource + name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + extension setting is expected, in this format: + + ``customers/{customer_id}/adGroupExtensionSettings/{ad_group_id}~{extension_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_extension_setting.AdGroupExtensionSetting, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group_extension_setting.AdGroupExtensionSetting, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupExtensionSettingsResponse(proto.Message): + r"""Response message for an ad group extension setting mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupExtensionSettingResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupExtensionSettingResult", + ) + + +class MutateAdGroupExtensionSettingResult(proto.Message): + r"""The result for the ad group extension setting mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_extension_setting (google.ads.googleads.v12.resources.types.AdGroupExtensionSetting): + The mutated AdGroupExtensionSetting with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_extension_setting = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_ad_group_extension_setting.AdGroupExtensionSetting, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_feed_service.py b/google/ads/googleads/v12/services/types/ad_group_feed_service.py new file mode 100644 index 000000000..c4e13ce97 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_feed_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_feed as gagr_ad_group_feed, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupFeedsRequest", + "AdGroupFeedOperation", + "MutateAdGroupFeedsResponse", + "MutateAdGroupFeedResult", + }, +) + + +class MutateAdGroupFeedsRequest(proto.Message): + r"""Request message for + [AdGroupFeedService.MutateAdGroupFeeds][google.ads.googleads.v12.services.AdGroupFeedService.MutateAdGroupFeeds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + group feeds are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupFeedOperation]): + Required. The list of operations to perform + on individual ad group feeds. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupFeedOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupFeedOperation(proto.Message): + r"""A single operation (create, update, remove) on an ad group + feed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AdGroupFeed): + Create operation: No resource name is + expected for the new ad group feed. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroupFeed): + Update operation: The ad group feed is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + feed is expected, in this format: + + ``customers/{customer_id}/adGroupFeeds/{ad_group_id}~{feed_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group_feed.AdGroupFeed, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group_feed.AdGroupFeed, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupFeedsResponse(proto.Message): + r"""Response message for an ad group feed mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupFeedResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupFeedResult", + ) + + +class MutateAdGroupFeedResult(proto.Message): + r"""The result for the ad group feed mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group_feed (google.ads.googleads.v12.resources.types.AdGroupFeed): + The mutated ad group feed with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group_feed = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_group_feed.AdGroupFeed, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_label_service.py b/google/ads/googleads/v12/services/types/ad_group_label_service.py new file mode 100644 index 000000000..64244fcc8 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_label_service.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ad_group_label +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupLabelsRequest", + "AdGroupLabelOperation", + "MutateAdGroupLabelsResponse", + "MutateAdGroupLabelResult", + }, +) + + +class MutateAdGroupLabelsRequest(proto.Message): + r"""Request message for + [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v12.services.AdGroupLabelService.MutateAdGroupLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose ad group + labels are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupLabelOperation]): + Required. The list of operations to perform + on ad group labels. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupLabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AdGroupLabelOperation(proto.Message): + r"""A single operation (create, remove) on an ad group label. + + 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: + create (google.ads.googleads.v12.resources.types.AdGroupLabel): + Create operation: No resource name is + expected for the new ad group label. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the ad group label + being removed, in this format: + + ``customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=ad_group_label.AdGroupLabel, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAdGroupLabelsResponse(proto.Message): + r"""Response message for an ad group labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupLabelResult", + ) + + +class MutateAdGroupLabelResult(proto.Message): + r"""The result for an ad group label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_group_service.py b/google/ads/googleads/v12/services/types/ad_group_service.py new file mode 100644 index 000000000..b81885425 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_group_service.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ad_group as gagr_ad_group +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdGroupsRequest", + "AdGroupOperation", + "MutateAdGroupsResponse", + "MutateAdGroupResult", + }, +) + + +class MutateAdGroupsRequest(proto.Message): + r"""Request message for + [AdGroupService.MutateAdGroups][google.ads.googleads.v12.services.AdGroupService.MutateAdGroups]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + groups are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdGroupOperation]): + Required. The list of operations to perform + on individual ad groups. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdGroupOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdGroupOperation(proto.Message): + r"""A single operation (create, update, remove) on an ad group. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AdGroup): + Create operation: No resource name is + expected for the new ad group. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdGroup): + Update operation: The ad group is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed ad group + is expected, in this format: + + ``customers/{customer_id}/adGroups/{ad_group_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_group.AdGroup, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_group.AdGroup, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdGroupsResponse(proto.Message): + r"""Response message for an ad group mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdGroupResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdGroupResult", + ) + + +class MutateAdGroupResult(proto.Message): + r"""The result for the ad group mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + ad_group (google.ads.googleads.v12.resources.types.AdGroup): + The mutated ad group with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_group = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_group.AdGroup, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_parameter_service.py b/google/ads/googleads/v12/services/types/ad_parameter_service.py new file mode 100644 index 000000000..2e17dffb7 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_parameter_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + ad_parameter as gagr_ad_parameter, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAdParametersRequest", + "AdParameterOperation", + "MutateAdParametersResponse", + "MutateAdParameterResult", + }, +) + + +class MutateAdParametersRequest(proto.Message): + r"""Request message for + [AdParameterService.MutateAdParameters][google.ads.googleads.v12.services.AdParameterService.MutateAdParameters] + + Attributes: + customer_id (str): + Required. The ID of the customer whose ad + parameters are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdParameterOperation]): + Required. The list of operations to perform + on individual ad parameters. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdParameterOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AdParameterOperation(proto.Message): + r"""A single operation (create, update, remove) on ad parameter. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AdParameter): + Create operation: No resource name is + expected for the new ad parameter. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AdParameter): + Update operation: The ad parameter is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the ad parameter to + remove is expected in this format: + + ``customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_ad_parameter.AdParameter, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_ad_parameter.AdParameter, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAdParametersResponse(proto.Message): + r"""Response message for an ad parameter mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdParameterResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdParameterResult", + ) + + +class MutateAdParameterResult(proto.Message): + r"""The result for the ad parameter mutate. + + Attributes: + resource_name (str): + The resource name returned for successful + operations. + ad_parameter (google.ads.googleads.v12.resources.types.AdParameter): + The mutated AdParameter with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad_parameter = proto.Field( + proto.MESSAGE, number=2, message=gagr_ad_parameter.AdParameter, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/ad_service.py b/google/ads/googleads/v12/services/types/ad_service.py new file mode 100644 index 000000000..38fdc3939 --- /dev/null +++ b/google/ads/googleads/v12/services/types/ad_service.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import policy +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ad as gagr_ad +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "GetAdRequest", + "MutateAdsRequest", + "AdOperation", + "MutateAdsResponse", + "MutateAdResult", + }, +) + + +class GetAdRequest(proto.Message): + r"""Request message for + [AdService.GetAd][google.ads.googleads.v12.services.AdService.GetAd]. + + Attributes: + resource_name (str): + Required. The resource name of the ad to + fetch. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class MutateAdsRequest(proto.Message): + r"""Request message for + [AdService.MutateAds][google.ads.googleads.v12.services.AdService.MutateAds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose ads + are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AdOperation]): + Required. The list of operations to perform + on individual ads. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AdOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class AdOperation(proto.Message): + r"""A single update operation on an ad. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + policy_validation_parameter (google.ads.googleads.v12.common.types.PolicyValidationParameter): + Configuration for how policies are validated. + update (google.ads.googleads.v12.resources.types.Ad): + Update operation: The ad is expected to have a valid + resource name in this format: + + ``customers/{customer_id}/ads/{ad_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + policy_validation_parameter = proto.Field( + proto.MESSAGE, number=3, message=policy.PolicyValidationParameter, + ) + update = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=gagr_ad.Ad, + ) + + +class MutateAdsResponse(proto.Message): + r"""Response message for an ad mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAdResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAdResult", + ) + + +class MutateAdResult(proto.Message): + r"""The result for the ad mutate. + + Attributes: + resource_name (str): + The resource name returned for successful + operations. + ad (google.ads.googleads.v12.resources.types.Ad): + The mutated ad with only mutable fields after mutate. The + field will only be returned when response_content_type is + set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + ad = proto.Field(proto.MESSAGE, number=2, message=gagr_ad.Ad,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_group_asset_service.py b/google/ads/googleads/v12/services/types/asset_group_asset_service.py new file mode 100644 index 000000000..f12e9d066 --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_group_asset_service.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import asset_group_asset +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetGroupAssetsRequest", + "AssetGroupAssetOperation", + "MutateAssetGroupAssetsResponse", + "MutateAssetGroupAssetResult", + }, +) + + +class MutateAssetGroupAssetsRequest(proto.Message): + r"""Request message for + [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v12.services.AssetGroupAssetService.MutateAssetGroupAssets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + group assets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupAssetOperation]): + Required. The list of operations to perform + on individual asset group assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetGroupAssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AssetGroupAssetOperation(proto.Message): + r"""A single operation (create, remove) on an asset group asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AssetGroupAsset): + Create operation: No resource name is + expected for the new asset group asset. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AssetGroupAsset): + Update operation: The asset group asset is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset + group asset is expected, in this format: + ``customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=asset_group_asset.AssetGroupAsset, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=asset_group_asset.AssetGroupAsset, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAssetGroupAssetsResponse(proto.Message): + r"""Response message for an asset group asset mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetGroupAssetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAssetGroupAssetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAssetGroupAssetResult(proto.Message): + r"""The result for the asset group asset mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_group_listing_group_filter_service.py b/google/ads/googleads/v12/services/types/asset_group_listing_group_filter_service.py new file mode 100644 index 000000000..123084aea --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_group_listing_group_filter_service.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_listing_group_filter as gagr_asset_group_listing_group_filter, +) +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetGroupListingGroupFiltersRequest", + "AssetGroupListingGroupFilterOperation", + "MutateAssetGroupListingGroupFiltersResponse", + "MutateAssetGroupListingGroupFilterResult", + }, +) + + +class MutateAssetGroupListingGroupFiltersRequest(proto.Message): + r"""Request message for + [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v12.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. + partial_failure is not supported because the tree needs to be + validated together. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + group listing group filters are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupListingGroupFilterOperation]): + Required. The list of operations to perform + on individual asset group listing group filters. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="AssetGroupListingGroupFilterOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AssetGroupListingGroupFilterOperation(proto.Message): + r"""A single operation (create, remove) on an asset group listing + group filter. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AssetGroupListingGroupFilter): + Create operation: No resource name is + expected for the new asset group listing group + filter. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AssetGroupListingGroupFilter): + Update operation: The asset group listing + group filter is expected to have a valid + resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset + group listing group filter is expected, in this format: + ``customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}`` + An entity can be removed only if it's not referenced by + other parent_listing_group_id. If multiple entities are + being deleted, the mutates must be in the correct order. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_asset_group_listing_group_filter.AssetGroupListingGroupFilter, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_asset_group_listing_group_filter.AssetGroupListingGroupFilter, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAssetGroupListingGroupFiltersResponse(proto.Message): + r"""Response message for an asset group listing group filter + mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetGroupListingGroupFilterResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="MutateAssetGroupListingGroupFilterResult", + ) + + +class MutateAssetGroupListingGroupFilterResult(proto.Message): + r"""The result for the asset group listing group filter mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + asset_group_listing_group_filter (google.ads.googleads.v12.resources.types.AssetGroupListingGroupFilter): + The mutated AssetGroupListingGroupFilter with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group_listing_group_filter = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_asset_group_listing_group_filter.AssetGroupListingGroupFilter, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_group_service.py b/google/ads/googleads/v12/services/types/asset_group_service.py new file mode 100644 index 000000000..073ccaec8 --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_group_service.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import asset_group +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetGroupsRequest", + "AssetGroupOperation", + "MutateAssetGroupsResponse", + "MutateAssetGroupResult", + }, +) + + +class MutateAssetGroupsRequest(proto.Message): + r"""Request message for + [AssetGroupService.MutateAssetGroups][google.ads.googleads.v12.services.AssetGroupService.MutateAssetGroups]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + groups are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupOperation]): + Required. The list of operations to perform + on individual asset groups. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetGroupOperation", + ) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AssetGroupOperation(proto.Message): + r"""A single operation (create, remove) on an asset group. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AssetGroup): + Create operation: No resource name is + expected for the new asset group + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AssetGroup): + Update operation: The asset group is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset + group is expected, in this format: + ``customers/{customer_id}/assetGroups/{asset_group_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=asset_group.AssetGroup, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=asset_group.AssetGroup, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAssetGroupsResponse(proto.Message): + r"""Response message for an asset group mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetGroupResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAssetGroupResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAssetGroupResult(proto.Message): + r"""The result for the asset group mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_group_signal_service.py b/google/ads/googleads/v12/services/types/asset_group_signal_service.py new file mode 100644 index 000000000..c564ce24b --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_group_signal_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_signal as gagr_asset_group_signal, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetGroupSignalsRequest", + "AssetGroupSignalOperation", + "MutateAssetGroupSignalsResponse", + "MutateAssetGroupSignalResult", + }, +) + + +class MutateAssetGroupSignalsRequest(proto.Message): + r"""Request message for + [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v12.services.AssetGroupSignalService.MutateAssetGroupSignals]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + group signals are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetGroupSignalOperation]): + Required. The list of operations to perform + on individual asset group signals. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetGroupSignalOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AssetGroupSignalOperation(proto.Message): + r"""A single operation (create, remove) on an asset group signal. + + 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: + create (google.ads.googleads.v12.resources.types.AssetGroupSignal): + Create operation: No resource name is + expected for the new asset group signal. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset + group signal is expected, in this format: + ``customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_asset_group_signal.AssetGroupSignal, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAssetGroupSignalsResponse(proto.Message): + r"""Response message for an asset group signal mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetGroupSignalResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAssetGroupSignalResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAssetGroupSignalResult(proto.Message): + r"""The result for the asset group signal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + asset_group_signal (google.ads.googleads.v12.resources.types.AssetGroupSignal): + The mutated AssetGroupSignal with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_group_signal = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_asset_group_signal.AssetGroupSignal, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_service.py b/google/ads/googleads/v12/services/types/asset_service.py new file mode 100644 index 000000000..a3160a3f2 --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_service.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import asset as gagr_asset +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetsRequest", + "AssetOperation", + "MutateAssetsResponse", + "MutateAssetResult", + }, +) + + +class MutateAssetsRequest(proto.Message): + r"""Request message for + [AssetService.MutateAssets][google.ads.googleads.v12.services.AssetService.MutateAssets] + + Attributes: + customer_id (str): + Required. The ID of the customer whose assets + are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetOperation]): + Required. The list of operations to perform + on individual assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=5,) + response_content_type = proto.Field( + proto.ENUM, + number=3, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class AssetOperation(proto.Message): + r"""A single operation to create an asset. Supported asset types + are YoutubeVideoAsset, MediaBundleAsset, ImageAsset, and + LeadFormAsset. TextAsset should be created with Ad inline. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Asset): + Create operation: No resource name is + expected for the new asset. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Asset): + Update operation: The asset is expected to have a valid + resource name in this format: + + ``customers/{customer_id}/assets/{asset_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=gagr_asset.Asset, + ) + update = proto.Field( + proto.MESSAGE, number=2, oneof="operation", message=gagr_asset.Asset, + ) + + +class MutateAssetsResponse(proto.Message): + r"""Response message for an asset mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateAssetResult", + ) + + +class MutateAssetResult(proto.Message): + r"""The result for the asset mutate. + + Attributes: + resource_name (str): + The resource name returned for successful + operations. + asset (google.ads.googleads.v12.resources.types.Asset): + The mutated asset with only mutable fields after mutate. The + field will only be returned when response_content_type is + set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset = proto.Field(proto.MESSAGE, number=2, message=gagr_asset.Asset,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_set_asset_service.py b/google/ads/googleads/v12/services/types/asset_set_asset_service.py new file mode 100644 index 000000000..d3f2d6ae2 --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_set_asset_service.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + asset_set_asset as gagr_asset_set_asset, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetSetAssetsRequest", + "AssetSetAssetOperation", + "MutateAssetSetAssetsResponse", + "MutateAssetSetAssetResult", + }, +) + + +class MutateAssetSetAssetsRequest(proto.Message): + r"""Request message for + [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v12.services.AssetSetAssetService.MutateAssetSetAssets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + set assets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetSetAssetOperation]): + Required. The list of operations to perform + on individual asset set assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetSetAssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AssetSetAssetOperation(proto.Message): + r"""A single operation (create, remove) on an asset set asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.AssetSetAsset): + Create operation: No resource name is + expected for the new asset set asset + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset set + asset is expected, in this format: + ``customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_asset_set_asset.AssetSetAsset, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateAssetSetAssetsResponse(proto.Message): + r"""Response message for an asset set asset mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetSetAssetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAssetSetAssetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAssetSetAssetResult(proto.Message): + r"""The result for the asset set asset mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + asset_set_asset (google.ads.googleads.v12.resources.types.AssetSetAsset): + The mutated asset set asset with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_set_asset = proto.Field( + proto.MESSAGE, number=2, message=gagr_asset_set_asset.AssetSetAsset, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/asset_set_service.py b/google/ads/googleads/v12/services/types/asset_set_service.py new file mode 100644 index 000000000..5897280b1 --- /dev/null +++ b/google/ads/googleads/v12/services/types/asset_set_service.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import asset_set as gagr_asset_set +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAssetSetsRequest", + "AssetSetOperation", + "MutateAssetSetsResponse", + "MutateAssetSetResult", + }, +) + + +class MutateAssetSetsRequest(proto.Message): + r"""Request message for + [AssetSetService.MutateAssetSets][google.ads.googleads.v12.services.AssetSetService.MutateAssetSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose asset + sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AssetSetOperation]): + Required. The list of operations to perform + on individual asset sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AssetSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class AssetSetOperation(proto.Message): + r"""A single operation (create, remove) on an asset set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.AssetSet): + Create operation: No resource name is + expected for the new asset set + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.AssetSet): + Update operation: The asset set is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed asset set + is expected, in this format: + ``customers/{customer_id}/assetSets/{asset_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_asset_set.AssetSet, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_asset_set.AssetSet, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateAssetSetsResponse(proto.Message): + r"""Response message for an asset set mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAssetSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAssetSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateAssetSetResult(proto.Message): + r"""The result for the asset set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + asset_set (google.ads.googleads.v12.resources.types.AssetSet): + The mutated asset set with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + asset_set = proto.Field( + proto.MESSAGE, number=2, message=gagr_asset_set.AssetSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/audience_insights_service.py b/google/ads/googleads/v12/services/types/audience_insights_service.py new file mode 100644 index 000000000..e9b9d1b8d --- /dev/null +++ b/google/ads/googleads/v12/services/types/audience_insights_service.py @@ -0,0 +1,782 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.enums.types import audience_insights_dimension + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "GenerateInsightsFinderReportRequest", + "GenerateInsightsFinderReportResponse", + "GenerateAudienceCompositionInsightsRequest", + "GenerateAudienceCompositionInsightsResponse", + "ListAudienceInsightsAttributesRequest", + "ListAudienceInsightsAttributesResponse", + "ListInsightsEligibleDatesRequest", + "ListInsightsEligibleDatesResponse", + "AudienceInsightsAttribute", + "AudienceInsightsTopic", + "AudienceInsightsEntity", + "AudienceInsightsCategory", + "AudienceInsightsDynamicLineup", + "BasicInsightsAudience", + "AudienceInsightsAttributeMetadata", + "YouTubeChannelAttributeMetadata", + "DynamicLineupAttributeMetadata", + "LocationAttributeMetadata", + "InsightsAudience", + "InsightsAudienceAttributeGroup", + "AudienceCompositionSection", + "AudienceCompositionAttributeCluster", + "AudienceCompositionMetrics", + "AudienceCompositionAttribute", + }, +) + + +class GenerateInsightsFinderReportRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v12.services.AudienceInsightsService.GenerateInsightsFinderReport]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + baseline_audience (google.ads.googleads.v12.services.types.BasicInsightsAudience): + Required. A baseline audience for this + report, typically all people in a region. + specific_audience (google.ads.googleads.v12.services.types.BasicInsightsAudience): + Required. The specific audience of interest + for this report. The insights in the report + will be based on attributes more prevalent in + this audience than in the report's baseline + audience. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + baseline_audience = proto.Field( + proto.MESSAGE, number=2, message="BasicInsightsAudience", + ) + specific_audience = proto.Field( + proto.MESSAGE, number=3, message="BasicInsightsAudience", + ) + customer_insights_group = proto.Field(proto.STRING, number=4,) + + +class GenerateInsightsFinderReportResponse(proto.Message): + r"""The response message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v12.services.AudienceInsightsService.GenerateInsightsFinderReport], + containing the shareable URL for the report. + + Attributes: + saved_report_url (str): + An HTTPS URL providing a deep link into the + Insights Finder UI with the report inputs filled + in according to the request. + """ + + saved_report_url = proto.Field(proto.STRING, number=1,) + + +class GenerateAudienceCompositionInsightsRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v12.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + audience (google.ads.googleads.v12.services.types.InsightsAudience): + Required. The audience of interest for which + insights are being requested. + data_month (str): + The one-month range of historical data to use + for insights, in the format "yyyy-mm". If unset, + insights will be returned for the last thirty + days of data. + dimensions (Sequence[google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The audience dimensions for which + composition insights should be returned. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + audience = proto.Field(proto.MESSAGE, number=2, message="InsightsAudience",) + data_month = proto.Field(proto.STRING, number=3,) + dimensions = proto.RepeatedField( + proto.ENUM, + number=4, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + customer_insights_group = proto.Field(proto.STRING, number=5,) + + +class GenerateAudienceCompositionInsightsResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v12.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + Attributes: + sections (Sequence[google.ads.googleads.v12.services.types.AudienceCompositionSection]): + The contents of the insights report, + organized into sections. Each section is + associated with one of the + AudienceInsightsDimension values in the request. + There may be more than one section per + dimension. + """ + + sections = proto.RepeatedField( + proto.MESSAGE, number=1, message="AudienceCompositionSection", + ) + + +class ListAudienceInsightsAttributesRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v12.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + dimensions (Sequence[google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes to be + returned. + query_text (str): + Required. A free text query. Attributes + matching or related to this string will be + returned. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + location_country_filters (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + If SUB_COUNTRY_LOCATION attributes are one of the requested + dimensions and this field is present, then the + SUB_COUNTRY_LOCATION attributes returned will be located in + these countries. If this field is absent, then location + attributes are not filtered by country. Setting this field + when SUB_COUNTRY_LOCATION attributes are not requested will + return an error. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + dimensions = proto.RepeatedField( + proto.ENUM, + number=2, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + query_text = proto.Field(proto.STRING, number=3,) + customer_insights_group = proto.Field(proto.STRING, number=4,) + location_country_filters = proto.RepeatedField( + proto.MESSAGE, number=5, message=criteria.LocationInfo, + ) + + +class ListAudienceInsightsAttributesResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v12.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + Attributes: + attributes (Sequence[google.ads.googleads.v12.services.types.AudienceInsightsAttributeMetadata]): + The attributes matching the search query. + """ + + attributes = proto.RepeatedField( + proto.MESSAGE, number=1, message="AudienceInsightsAttributeMetadata", + ) + + +class ListInsightsEligibleDatesRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.ListAudienceInsightsDates][]. + + """ + + +class ListInsightsEligibleDatesResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.ListAudienceInsightsDates][]. + + Attributes: + data_months (Sequence[str]): + The months for which AudienceInsights data is + currently available, each represented as a + string in the form "YYYY-MM". + """ + + data_months = proto.RepeatedField(proto.STRING, number=1,) + + +class AudienceInsightsAttribute(proto.Message): + r"""An audience attribute that can be used to request insights + about the audience. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + age_range (google.ads.googleads.v12.common.types.AgeRangeInfo): + An audience attribute defined by an age + range. + + This field is a member of `oneof`_ ``attribute``. + gender (google.ads.googleads.v12.common.types.GenderInfo): + An audience attribute defined by a gender. + + This field is a member of `oneof`_ ``attribute``. + location (google.ads.googleads.v12.common.types.LocationInfo): + An audience attribute defined by a geographic + location. + + This field is a member of `oneof`_ ``attribute``. + user_interest (google.ads.googleads.v12.common.types.UserInterestInfo): + An Affinity or In-Market audience. + + This field is a member of `oneof`_ ``attribute``. + entity (google.ads.googleads.v12.services.types.AudienceInsightsEntity): + An audience attribute defined by interest in + a topic represented by a Knowledge Graph entity. + + This field is a member of `oneof`_ ``attribute``. + category (google.ads.googleads.v12.services.types.AudienceInsightsCategory): + An audience attribute defined by interest in + a Product & Service category. + + This field is a member of `oneof`_ ``attribute``. + dynamic_lineup (google.ads.googleads.v12.services.types.AudienceInsightsDynamicLineup): + A YouTube Dynamic Lineup + + This field is a member of `oneof`_ ``attribute``. + parental_status (google.ads.googleads.v12.common.types.ParentalStatusInfo): + A Parental Status value (parent, or not a + parent). + + This field is a member of `oneof`_ ``attribute``. + income_range (google.ads.googleads.v12.common.types.IncomeRangeInfo): + A household income percentile range. + + This field is a member of `oneof`_ ``attribute``. + youtube_channel (google.ads.googleads.v12.common.types.YouTubeChannelInfo): + A YouTube channel. + + This field is a member of `oneof`_ ``attribute``. + """ + + age_range = proto.Field( + proto.MESSAGE, + number=1, + oneof="attribute", + message=criteria.AgeRangeInfo, + ) + gender = proto.Field( + proto.MESSAGE, number=2, oneof="attribute", message=criteria.GenderInfo, + ) + location = proto.Field( + proto.MESSAGE, + number=3, + oneof="attribute", + message=criteria.LocationInfo, + ) + user_interest = proto.Field( + proto.MESSAGE, + number=4, + oneof="attribute", + message=criteria.UserInterestInfo, + ) + entity = proto.Field( + proto.MESSAGE, + number=5, + oneof="attribute", + message="AudienceInsightsEntity", + ) + category = proto.Field( + proto.MESSAGE, + number=6, + oneof="attribute", + message="AudienceInsightsCategory", + ) + dynamic_lineup = proto.Field( + proto.MESSAGE, + number=7, + oneof="attribute", + message="AudienceInsightsDynamicLineup", + ) + parental_status = proto.Field( + proto.MESSAGE, + number=8, + oneof="attribute", + message=criteria.ParentalStatusInfo, + ) + income_range = proto.Field( + proto.MESSAGE, + number=9, + oneof="attribute", + message=criteria.IncomeRangeInfo, + ) + youtube_channel = proto.Field( + proto.MESSAGE, + number=10, + oneof="attribute", + message=criteria.YouTubeChannelInfo, + ) + + +class AudienceInsightsTopic(proto.Message): + r"""An entity or category representing a topic that defines an + audience. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + entity (google.ads.googleads.v12.services.types.AudienceInsightsEntity): + A Knowledge Graph entity + + This field is a member of `oneof`_ ``topic``. + category (google.ads.googleads.v12.services.types.AudienceInsightsCategory): + A Product & Service category + + This field is a member of `oneof`_ ``topic``. + """ + + entity = proto.Field( + proto.MESSAGE, + number=1, + oneof="topic", + message="AudienceInsightsEntity", + ) + category = proto.Field( + proto.MESSAGE, + number=2, + oneof="topic", + message="AudienceInsightsCategory", + ) + + +class AudienceInsightsEntity(proto.Message): + r"""A Knowledge Graph entity, represented by its machine id. + + Attributes: + knowledge_graph_machine_id (str): + Required. The machine id (mid) of the + Knowledge Graph entity. + """ + + knowledge_graph_machine_id = proto.Field(proto.STRING, number=1,) + + +class AudienceInsightsCategory(proto.Message): + r"""A Product and Service category. + + Attributes: + category_id (str): + Required. The criterion id of the category. + """ + + category_id = proto.Field(proto.STRING, number=1,) + + +class AudienceInsightsDynamicLineup(proto.Message): + r"""A YouTube Dynamic Lineup. + + Attributes: + dynamic_lineup_id (str): + Required. The numeric ID of the dynamic + lineup. + """ + + dynamic_lineup_id = proto.Field(proto.STRING, number=1,) + + +class BasicInsightsAudience(proto.Message): + r"""A description of an audience used for requesting insights. + + Attributes: + country_location (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + Required. The countries for this audience. + sub_country_locations (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + Sub-country geographic location attributes. + If present, each of these must be contained in + one of the countries in this audience. + gender (google.ads.googleads.v12.common.types.GenderInfo): + Gender for the audience. If absent, the + audience does not restrict by gender. + age_ranges (Sequence[google.ads.googleads.v12.common.types.AgeRangeInfo]): + Age ranges for the audience. If absent, the + audience represents all people over 18 that + match the other attributes. + user_interests (Sequence[google.ads.googleads.v12.common.types.UserInterestInfo]): + User interests defining this audience. + Affinity and In-Market audiences are supported. + topics (Sequence[google.ads.googleads.v12.services.types.AudienceInsightsTopic]): + Topics, represented by Knowledge Graph + entities and/or Product & Service categories, + that this audience is interested in. + """ + + country_location = proto.RepeatedField( + proto.MESSAGE, number=1, message=criteria.LocationInfo, + ) + sub_country_locations = proto.RepeatedField( + proto.MESSAGE, number=2, message=criteria.LocationInfo, + ) + gender = proto.Field(proto.MESSAGE, number=3, message=criteria.GenderInfo,) + age_ranges = proto.RepeatedField( + proto.MESSAGE, number=4, message=criteria.AgeRangeInfo, + ) + user_interests = proto.RepeatedField( + proto.MESSAGE, number=5, message=criteria.UserInterestInfo, + ) + topics = proto.RepeatedField( + proto.MESSAGE, number=6, message="AudienceInsightsTopic", + ) + + +class AudienceInsightsAttributeMetadata(proto.Message): + r"""An audience attribute, with metadata about it, returned in + response to a search. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + dimension (google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): + The type of the attribute. + attribute (google.ads.googleads.v12.services.types.AudienceInsightsAttribute): + The attribute itself. + display_name (str): + The human-readable name of the attribute. + score (float): + A relevance score for this attribute, between + 0 and 1. + display_info (str): + A string that supplements the display_name to identify the + attribute. If the dimension is TOPIC, this is a brief + description of the Knowledge Graph entity, such as "American + singer-songwriter". If the dimension is CATEGORY, this is + the complete path to the category in The Product & Service + taxonomy, for example "/Apparel/Clothing/Outerwear". + youtube_channel_metadata (google.ads.googleads.v12.services.types.YouTubeChannelAttributeMetadata): + Special metadata for a YouTube channel. + + This field is a member of `oneof`_ ``dimension_metadata``. + dynamic_attribute_metadata (google.ads.googleads.v12.services.types.DynamicLineupAttributeMetadata): + Special metadata for a YouTube Dynamic + Lineup. + + This field is a member of `oneof`_ ``dimension_metadata``. + location_attribute_metadata (google.ads.googleads.v12.services.types.LocationAttributeMetadata): + Special metadata for a Location. + + This field is a member of `oneof`_ ``dimension_metadata``. + """ + + dimension = proto.Field( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + attribute = proto.Field( + proto.MESSAGE, number=2, message="AudienceInsightsAttribute", + ) + display_name = proto.Field(proto.STRING, number=3,) + score = proto.Field(proto.DOUBLE, number=4,) + display_info = proto.Field(proto.STRING, number=5,) + youtube_channel_metadata = proto.Field( + proto.MESSAGE, + number=6, + oneof="dimension_metadata", + message="YouTubeChannelAttributeMetadata", + ) + dynamic_attribute_metadata = proto.Field( + proto.MESSAGE, + number=7, + oneof="dimension_metadata", + message="DynamicLineupAttributeMetadata", + ) + location_attribute_metadata = proto.Field( + proto.MESSAGE, + number=8, + oneof="dimension_metadata", + message="LocationAttributeMetadata", + ) + + +class YouTubeChannelAttributeMetadata(proto.Message): + r"""Metadata associated with a YouTube channel attribute. + + Attributes: + subscriber_count (int): + The approximate number of subscribers to the + YouTube channel. + """ + + subscriber_count = proto.Field(proto.INT64, number=1,) + + +class DynamicLineupAttributeMetadata(proto.Message): + r"""Metadata associated with a Dynamic Lineup attribute. + + Attributes: + inventory_country (google.ads.googleads.v12.common.types.LocationInfo): + The national market associated with the + lineup. + median_monthly_inventory (int): + The median number of impressions per month on + this lineup. + + This field is a member of `oneof`_ ``_median_monthly_inventory``. + channel_count_lower_bound (int): + The lower end of a range containing the + number of channels in the lineup. + + This field is a member of `oneof`_ ``_channel_count_lower_bound``. + channel_count_upper_bound (int): + The upper end of a range containing the + number of channels in the lineup. + + This field is a member of `oneof`_ ``_channel_count_upper_bound``. + """ + + inventory_country = proto.Field( + proto.MESSAGE, number=1, message=criteria.LocationInfo, + ) + median_monthly_inventory = proto.Field( + proto.INT64, number=2, optional=True, + ) + channel_count_lower_bound = proto.Field( + proto.INT64, number=3, optional=True, + ) + channel_count_upper_bound = proto.Field( + proto.INT64, number=4, optional=True, + ) + + +class LocationAttributeMetadata(proto.Message): + r"""Metadata associated with a Location attribute. + + Attributes: + country_location (google.ads.googleads.v12.common.types.LocationInfo): + The country location of the sub country + location. + """ + + country_location = proto.Field( + proto.MESSAGE, number=1, message=criteria.LocationInfo, + ) + + +class InsightsAudience(proto.Message): + r"""A set of users, defined by various characteristics, for which + insights can be requested in AudienceInsightsService. + + Attributes: + country_locations (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + Required. The countries for the audience. + sub_country_locations (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + Sub-country geographic location attributes. If present, each + of these must be contained in one of the countries in this + audience. If absent, the audience is geographically to the + country_locations and no further. + gender (google.ads.googleads.v12.common.types.GenderInfo): + Gender for the audience. If absent, the + audience does not restrict by gender. + age_ranges (Sequence[google.ads.googleads.v12.common.types.AgeRangeInfo]): + Age ranges for the audience. If absent, the + audience represents all people over 18 that + match the other attributes. + parental_status (google.ads.googleads.v12.common.types.ParentalStatusInfo): + Parental status for the audience. If absent, + the audience does not restrict by parental + status. + income_ranges (Sequence[google.ads.googleads.v12.common.types.IncomeRangeInfo]): + Household income percentile ranges for the + audience. If absent, the audience does not + restrict by household income range. + dynamic_lineups (Sequence[google.ads.googleads.v12.services.types.AudienceInsightsDynamicLineup]): + Dynamic lineups representing the YouTube + content viewed by the audience. + topic_audience_combinations (Sequence[google.ads.googleads.v12.services.types.InsightsAudienceAttributeGroup]): + A combination of entity, category and user + interest attributes defining the audience. The + combination has a logical AND-of-ORs structure: + Attributes within each + InsightsAudienceAttributeGroup are combined with + OR, and the combinations themselves are combined + together with AND. For example, the expression + (Entity OR Affinity) AND (In-Market OR Category) + can be formed using two + InsightsAudienceAttributeGroups with two + Attributes each. + """ + + country_locations = proto.RepeatedField( + proto.MESSAGE, number=1, message=criteria.LocationInfo, + ) + sub_country_locations = proto.RepeatedField( + proto.MESSAGE, number=2, message=criteria.LocationInfo, + ) + gender = proto.Field(proto.MESSAGE, number=3, message=criteria.GenderInfo,) + age_ranges = proto.RepeatedField( + proto.MESSAGE, number=4, message=criteria.AgeRangeInfo, + ) + parental_status = proto.Field( + proto.MESSAGE, number=5, message=criteria.ParentalStatusInfo, + ) + income_ranges = proto.RepeatedField( + proto.MESSAGE, number=6, message=criteria.IncomeRangeInfo, + ) + dynamic_lineups = proto.RepeatedField( + proto.MESSAGE, number=7, message="AudienceInsightsDynamicLineup", + ) + topic_audience_combinations = proto.RepeatedField( + proto.MESSAGE, number=8, message="InsightsAudienceAttributeGroup", + ) + + +class InsightsAudienceAttributeGroup(proto.Message): + r"""A list of AudienceInsightsAttributes. + + Attributes: + attributes (Sequence[google.ads.googleads.v12.services.types.AudienceInsightsAttribute]): + Required. A collection of audience attributes + to be combined with logical OR. Attributes need + not all be the same dimension. Only Knowledge + Graph entities, Product & Service Categories, + and Affinity and In-Market audiences are + supported in this context. + """ + + attributes = proto.RepeatedField( + proto.MESSAGE, number=1, message="AudienceInsightsAttribute", + ) + + +class AudienceCompositionSection(proto.Message): + r"""A collection of related attributes of the same type in an + audience composition insights report. + + Attributes: + dimension (google.ads.googleads.v12.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): + The type of the attributes in this section. + top_attributes (Sequence[google.ads.googleads.v12.services.types.AudienceCompositionAttribute]): + The most relevant segments for this audience. If dimension + is GENDER, AGE_RANGE or PARENTAL_STATUS, then this list of + attributes is exhaustive. + clustered_attributes (Sequence[google.ads.googleads.v12.services.types.AudienceCompositionAttributeCluster]): + Additional attributes for this audience, grouped into + clusters. Only populated if dimension is YOUTUBE_CHANNEL. + """ + + dimension = proto.Field( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + top_attributes = proto.RepeatedField( + proto.MESSAGE, number=3, message="AudienceCompositionAttribute", + ) + clustered_attributes = proto.RepeatedField( + proto.MESSAGE, number=4, message="AudienceCompositionAttributeCluster", + ) + + +class AudienceCompositionAttributeCluster(proto.Message): + r"""A collection of related attributes, with metadata and + metrics, in an audience composition insights report. + + Attributes: + cluster_display_name (str): + The name of this cluster of attributes + cluster_metrics (google.ads.googleads.v12.services.types.AudienceCompositionMetrics): + If the dimension associated with this cluster is + YOUTUBE_CHANNEL, then cluster_metrics are metrics associated + with the cluster as a whole. For other dimensions, this + field is unset. + attributes (Sequence[google.ads.googleads.v12.services.types.AudienceCompositionAttribute]): + The individual attributes that make up this + cluster, with metadata and metrics. + """ + + cluster_display_name = proto.Field(proto.STRING, number=1,) + cluster_metrics = proto.Field( + proto.MESSAGE, number=3, message="AudienceCompositionMetrics", + ) + attributes = proto.RepeatedField( + proto.MESSAGE, number=4, message="AudienceCompositionAttribute", + ) + + +class AudienceCompositionMetrics(proto.Message): + r"""The share and index metrics associated with an attribute in + an audience composition insights report. + + Attributes: + baseline_audience_share (float): + The fraction (from 0 to 1 inclusive) of the + baseline audience that match the attribute. + audience_share (float): + The fraction (from 0 to 1 inclusive) of the + specific audience that match the attribute. + index (float): + The ratio of audience_share to baseline_audience_share, or + zero if this ratio is undefined or is not meaningful. + score (float): + A relevance score from 0 to 1 inclusive. + """ + + baseline_audience_share = proto.Field(proto.DOUBLE, number=1,) + audience_share = proto.Field(proto.DOUBLE, number=2,) + index = proto.Field(proto.DOUBLE, number=3,) + score = proto.Field(proto.DOUBLE, number=4,) + + +class AudienceCompositionAttribute(proto.Message): + r"""An audience attribute with metadata and metrics. + + Attributes: + attribute_metadata (google.ads.googleads.v12.services.types.AudienceInsightsAttributeMetadata): + The attribute with its metadata. + metrics (google.ads.googleads.v12.services.types.AudienceCompositionMetrics): + Share and index metrics for the attribute. + """ + + attribute_metadata = proto.Field( + proto.MESSAGE, number=1, message="AudienceInsightsAttributeMetadata", + ) + metrics = proto.Field( + proto.MESSAGE, number=2, message="AudienceCompositionMetrics", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/audience_service.py b/google/ads/googleads/v12/services/types/audience_service.py new file mode 100644 index 000000000..eb2b426b6 --- /dev/null +++ b/google/ads/googleads/v12/services/types/audience_service.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import audience as gagr_audience +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateAudiencesRequest", + "MutateAudiencesResponse", + "AudienceOperation", + "MutateAudienceResult", + }, +) + + +class MutateAudiencesRequest(proto.Message): + r"""Request message for + [AudienceService.MutateAudiences][google.ads.googleads.v12.services.AudienceService.MutateAudiences]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + audiences are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.AudienceOperation]): + Required. The list of operations to perform + on individual audiences. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="AudienceOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class MutateAudiencesResponse(proto.Message): + r"""Response message for an audience mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateAudienceResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateAudienceResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class AudienceOperation(proto.Message): + r"""A single operation (create, update) on an audience. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Audience): + Create operation: No resource name is + expected for the new audience + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Audience): + Update operation: The audience is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_audience.Audience, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_audience.Audience, + ) + + +class MutateAudienceResult(proto.Message): + r"""The result for the audience mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + audience (google.ads.googleads.v12.resources.types.Audience): + The mutated Audience with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + audience = proto.Field( + proto.MESSAGE, number=2, message=gagr_audience.Audience, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/batch_job_service.py b/google/ads/googleads/v12/services/types/batch_job_service.py new file mode 100644 index 000000000..5d5f3a7de --- /dev/null +++ b/google/ads/googleads/v12/services/types/batch_job_service.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import batch_job +from google.ads.googleads.v12.services.types import google_ads_service +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateBatchJobRequest", + "BatchJobOperation", + "MutateBatchJobResponse", + "MutateBatchJobResult", + "RunBatchJobRequest", + "AddBatchJobOperationsRequest", + "AddBatchJobOperationsResponse", + "ListBatchJobResultsRequest", + "ListBatchJobResultsResponse", + "BatchJobResult", + }, +) + + +class MutateBatchJobRequest(proto.Message): + r"""Request message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v12.services.BatchJobService.MutateBatchJob]. + + Attributes: + customer_id (str): + Required. The ID of the customer for which to + create a batch job. + operation (google.ads.googleads.v12.services.types.BatchJobOperation): + Required. The operation to perform on an + individual batch job. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="BatchJobOperation", + ) + + +class BatchJobOperation(proto.Message): + r"""A single operation on a batch job. + + 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: + create (google.ads.googleads.v12.resources.types.BatchJob): + Create operation: No resource name is + expected for the new batch job. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: The batch job must not have been run. A + resource name for the removed batch job is expected, in this + format: + + ``customers/{customer_id}/batchJobs/{batch_job_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=batch_job.BatchJob, + ) + remove = proto.Field(proto.STRING, number=4, oneof="operation",) + + +class MutateBatchJobResponse(proto.Message): + r"""Response message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v12.services.BatchJobService.MutateBatchJob]. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateBatchJobResult): + The result for the mutate. + """ + + result = proto.Field( + proto.MESSAGE, number=1, message="MutateBatchJobResult", + ) + + +class MutateBatchJobResult(proto.Message): + r"""The result for the batch job mutate. + + Attributes: + resource_name (str): + The resource name of the batch job. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class RunBatchJobRequest(proto.Message): + r"""Request message for + [BatchJobService.RunBatchJob][google.ads.googleads.v12.services.BatchJobService.RunBatchJob]. + + Attributes: + resource_name (str): + Required. The resource name of the BatchJob + to run. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class AddBatchJobOperationsRequest(proto.Message): + r"""Request message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v12.services.BatchJobService.AddBatchJobOperations]. + + Attributes: + resource_name (str): + Required. The resource name of the batch job. + sequence_token (str): + A token used to enforce sequencing. + + The first AddBatchJobOperations request for a batch job + should not set sequence_token. Subsequent requests must set + sequence_token to the value of next_sequence_token received + in the previous AddBatchJobOperations response. + mutate_operations (Sequence[google.ads.googleads.v12.services.types.MutateOperation]): + Required. The list of mutates being added. + Operations can use negative integers as temp ids + to signify dependencies between entities created + in this batch job. For example, a customer with + id = 1234 can create a campaign and an ad group + in that same campaign by creating a campaign in + the first operation with the resource name + explicitly set to "customers/1234/campaigns/-1", + and creating an ad group in the second operation + with the campaign field also set to + "customers/1234/campaigns/-1". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + sequence_token = proto.Field(proto.STRING, number=2,) + mutate_operations = proto.RepeatedField( + proto.MESSAGE, number=3, message=google_ads_service.MutateOperation, + ) + + +class AddBatchJobOperationsResponse(proto.Message): + r"""Response message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v12.services.BatchJobService.AddBatchJobOperations]. + + Attributes: + total_operations (int): + The total number of operations added so far + for this batch job. + next_sequence_token (str): + The sequence token to be used when calling + AddBatchJobOperations again if more operations need to be + added. The next AddBatchJobOperations request must set the + sequence_token field to the value of this field. + """ + + total_operations = proto.Field(proto.INT64, number=1,) + next_sequence_token = proto.Field(proto.STRING, number=2,) + + +class ListBatchJobResultsRequest(proto.Message): + r"""Request message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v12.services.BatchJobService.ListBatchJobResults]. + + Attributes: + resource_name (str): + Required. The resource name of the batch job + whose results are being listed. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. Use the value obtained + from ``next_page_token`` in the previous response in order + to request the next page of results. + page_size (int): + Number of elements to retrieve in a single + page. When a page request is too large, the + server may decide to further limit the number of + returned resources. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + page_token = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ListBatchJobResultsResponse(proto.Message): + r"""Response message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v12.services.BatchJobService.ListBatchJobResults]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.BatchJobResult]): + The list of rows that matched the query. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + """ + + @property + def raw_page(self): + return self + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="BatchJobResult", + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class BatchJobResult(proto.Message): + r"""An individual batch job result. + + Attributes: + operation_index (int): + Index of the mutate operation. + mutate_operation_response (google.ads.googleads.v12.services.types.MutateOperationResponse): + Response for the mutate. + May be empty if errors occurred. + status (google.rpc.status_pb2.Status): + Details of the errors when processing the + operation. + """ + + operation_index = proto.Field(proto.INT64, number=1,) + mutate_operation_response = proto.Field( + proto.MESSAGE, + number=2, + message=google_ads_service.MutateOperationResponse, + ) + status = proto.Field(proto.MESSAGE, number=3, message=status_pb2.Status,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/bidding_data_exclusion_service.py b/google/ads/googleads/v12/services/types/bidding_data_exclusion_service.py new file mode 100644 index 000000000..b25620a41 --- /dev/null +++ b/google/ads/googleads/v12/services/types/bidding_data_exclusion_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + bidding_data_exclusion as gagr_bidding_data_exclusion, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateBiddingDataExclusionsRequest", + "BiddingDataExclusionOperation", + "MutateBiddingDataExclusionsResponse", + "MutateBiddingDataExclusionsResult", + }, +) + + +class MutateBiddingDataExclusionsRequest(proto.Message): + r"""Request message for + [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v12.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. + + Attributes: + customer_id (str): + Required. ID of the customer whose data + exclusions are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingDataExclusionOperation]): + Required. The list of operations to perform + on individual data exclusions. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="BiddingDataExclusionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class BiddingDataExclusionOperation(proto.Message): + r"""A single operation (create, remove, update) on a data + exclusion. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.BiddingDataExclusion): + Create operation: No resource name is + expected for the new data exclusion. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.BiddingDataExclusion): + Update operation: The data exclusion is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed data + exclusion is expected, in this format: + + ``customers/{customer_id}/biddingDataExclusions/{data_exclusion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_bidding_data_exclusion.BiddingDataExclusion, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_bidding_data_exclusion.BiddingDataExclusion, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateBiddingDataExclusionsResponse(proto.Message): + r"""Response message for data exlusions mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateBiddingDataExclusionsResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateBiddingDataExclusionsResult", + ) + + +class MutateBiddingDataExclusionsResult(proto.Message): + r"""The result for the data exclusion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + bidding_data_exclusion (google.ads.googleads.v12.resources.types.BiddingDataExclusion): + The mutated bidding data exclusion with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + bidding_data_exclusion = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_bidding_data_exclusion.BiddingDataExclusion, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/bidding_seasonality_adjustment_service.py b/google/ads/googleads/v12/services/types/bidding_seasonality_adjustment_service.py new file mode 100644 index 000000000..744ed80fa --- /dev/null +++ b/google/ads/googleads/v12/services/types/bidding_seasonality_adjustment_service.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + bidding_seasonality_adjustment as gagr_bidding_seasonality_adjustment, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateBiddingSeasonalityAdjustmentsRequest", + "BiddingSeasonalityAdjustmentOperation", + "MutateBiddingSeasonalityAdjustmentsResponse", + "MutateBiddingSeasonalityAdjustmentsResult", + }, +) + + +class MutateBiddingSeasonalityAdjustmentsRequest(proto.Message): + r"""Request message for + [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v12.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. + + Attributes: + customer_id (str): + Required. ID of the customer whose + seasonality adjustments are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingSeasonalityAdjustmentOperation]): + Required. The list of operations to perform + on individual seasonality adjustments. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="BiddingSeasonalityAdjustmentOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class BiddingSeasonalityAdjustmentOperation(proto.Message): + r"""A single operation (create, remove, update) on a seasonality + adjustment. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.BiddingSeasonalityAdjustment): + Create operation: No resource name is + expected for the new seasonality adjustment. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.BiddingSeasonalityAdjustment): + Update operation: The seasonality adjustment + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed + seasonality adjustment is expected, in this format: + + ``customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_adjustment_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_bidding_seasonality_adjustment.BiddingSeasonalityAdjustment, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_bidding_seasonality_adjustment.BiddingSeasonalityAdjustment, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateBiddingSeasonalityAdjustmentsResponse(proto.Message): + r"""Response message for seasonality adjustments mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateBiddingSeasonalityAdjustmentsResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MutateBiddingSeasonalityAdjustmentsResult", + ) + + +class MutateBiddingSeasonalityAdjustmentsResult(proto.Message): + r"""The result for the seasonality adjustment mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + bidding_seasonality_adjustment (google.ads.googleads.v12.resources.types.BiddingSeasonalityAdjustment): + The mutated bidding seasonality adjustment with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + bidding_seasonality_adjustment = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_bidding_seasonality_adjustment.BiddingSeasonalityAdjustment, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/bidding_strategy_service.py b/google/ads/googleads/v12/services/types/bidding_strategy_service.py new file mode 100644 index 000000000..dc0127366 --- /dev/null +++ b/google/ads/googleads/v12/services/types/bidding_strategy_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + bidding_strategy as gagr_bidding_strategy, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateBiddingStrategiesRequest", + "BiddingStrategyOperation", + "MutateBiddingStrategiesResponse", + "MutateBiddingStrategyResult", + }, +) + + +class MutateBiddingStrategiesRequest(proto.Message): + r"""Request message for + [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v12.services.BiddingStrategyService.MutateBiddingStrategies]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + bidding strategies are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.BiddingStrategyOperation]): + Required. The list of operations to perform + on individual bidding strategies. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="BiddingStrategyOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class BiddingStrategyOperation(proto.Message): + r"""A single operation (create, update, remove) on a bidding + strategy. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.BiddingStrategy): + Create operation: No resource name is + expected for the new bidding strategy. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.BiddingStrategy): + Update operation: The bidding strategy is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed bidding + strategy is expected, in this format: + + ``customers/{customer_id}/biddingStrategies/{bidding_strategy_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_bidding_strategy.BiddingStrategy, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_bidding_strategy.BiddingStrategy, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateBiddingStrategiesResponse(proto.Message): + r"""Response message for bidding strategy mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateBiddingStrategyResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateBiddingStrategyResult", + ) + + +class MutateBiddingStrategyResult(proto.Message): + r"""The result for the bidding strategy mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + bidding_strategy (google.ads.googleads.v12.resources.types.BiddingStrategy): + The mutated bidding strategy with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + bidding_strategy = proto.Field( + proto.MESSAGE, number=2, message=gagr_bidding_strategy.BiddingStrategy, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/billing_setup_service.py b/google/ads/googleads/v12/services/types/billing_setup_service.py new file mode 100644 index 000000000..bc6c123c8 --- /dev/null +++ b/google/ads/googleads/v12/services/types/billing_setup_service.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import billing_setup + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateBillingSetupRequest", + "BillingSetupOperation", + "MutateBillingSetupResponse", + "MutateBillingSetupResult", + }, +) + + +class MutateBillingSetupRequest(proto.Message): + r"""Request message for billing setup mutate operations. + + Attributes: + customer_id (str): + Required. Id of the customer to apply the + billing setup mutate operation to. + operation (google.ads.googleads.v12.services.types.BillingSetupOperation): + Required. The operation to perform. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="BillingSetupOperation", + ) + + +class BillingSetupOperation(proto.Message): + r"""A single operation on a billing setup, which describes the + cancellation of an existing billing setup. + + 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: + create (google.ads.googleads.v12.resources.types.BillingSetup): + Creates a billing setup. No resource name is + expected for the new billing setup. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Resource name of the billing setup to remove. A setup cannot + be removed unless it is in a pending state or its scheduled + start time is in the future. The resource name looks like + ``customers/{customer_id}/billingSetups/{billing_id}``. + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=billing_setup.BillingSetup, + ) + remove = proto.Field(proto.STRING, number=1, oneof="operation",) + + +class MutateBillingSetupResponse(proto.Message): + r"""Response message for a billing setup operation. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateBillingSetupResult): + A result that identifies the resource + affected by the mutate request. + """ + + result = proto.Field( + proto.MESSAGE, number=1, message="MutateBillingSetupResult", + ) + + +class MutateBillingSetupResult(proto.Message): + r"""Result for a single billing setup mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_asset_service.py b/google/ads/googleads/v12/services/types/campaign_asset_service.py new file mode 100644 index 000000000..d1d8dba03 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_asset_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_asset as gagr_campaign_asset, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignAssetsRequest", + "CampaignAssetOperation", + "MutateCampaignAssetsResponse", + "MutateCampaignAssetResult", + }, +) + + +class MutateCampaignAssetsRequest(proto.Message): + r"""Request message for + [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v12.services.CampaignAssetService.MutateCampaignAssets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign assets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignAssetOperation]): + Required. The list of operations to perform + on individual campaign assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignAssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignAssetOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignAsset): + Create operation: No resource name is + expected for the new campaign asset. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignAsset): + Update operation: The campaign asset is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + asset is expected, in this format: + + ``customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_asset.CampaignAsset, + ) + update = proto.Field( + proto.MESSAGE, + number=3, + oneof="operation", + message=gagr_campaign_asset.CampaignAsset, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCampaignAssetsResponse(proto.Message): + r"""Response message for a campaign asset mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignAssetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignAssetResult", + ) + + +class MutateCampaignAssetResult(proto.Message): + r"""The result for the campaign asset mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_asset (google.ads.googleads.v12.resources.types.CampaignAsset): + The mutated campaign asset with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_asset = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign_asset.CampaignAsset, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_asset_set_service.py b/google/ads/googleads/v12/services/types/campaign_asset_set_service.py new file mode 100644 index 000000000..5e0c43427 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_asset_set_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_asset_set as gagr_campaign_asset_set, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignAssetSetsRequest", + "CampaignAssetSetOperation", + "MutateCampaignAssetSetsResponse", + "MutateCampaignAssetSetResult", + }, +) + + +class MutateCampaignAssetSetsRequest(proto.Message): + r"""Request message for + [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v12.services.CampaignAssetSetService.MutateCampaignAssetSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign asset sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignAssetSetOperation]): + Required. The list of operations to perform + on individual campaign asset sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignAssetSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignAssetSetOperation(proto.Message): + r"""A single operation (create, remove) on a campaign asset set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.CampaignAssetSet): + Create operation: No resource name is + expected for the new campaign asset set. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + asset set is expected, in this format: + ``customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_asset_set.CampaignAssetSet, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCampaignAssetSetsResponse(proto.Message): + r"""Response message for a campaign asset set mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignAssetSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCampaignAssetSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateCampaignAssetSetResult(proto.Message): + r"""The result for the campaign asset set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_asset_set (google.ads.googleads.v12.resources.types.CampaignAssetSet): + The mutated campaign asset set with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_asset_set = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_asset_set.CampaignAssetSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_bid_modifier_service.py b/google/ads/googleads/v12/services/types/campaign_bid_modifier_service.py new file mode 100644 index 000000000..2a207d731 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_bid_modifier_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_bid_modifier as gagr_campaign_bid_modifier, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignBidModifiersRequest", + "CampaignBidModifierOperation", + "MutateCampaignBidModifiersResponse", + "MutateCampaignBidModifierResult", + }, +) + + +class MutateCampaignBidModifiersRequest(proto.Message): + r"""Request message for + [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v12.services.CampaignBidModifierService.MutateCampaignBidModifiers]. + + Attributes: + customer_id (str): + Required. ID of the customer whose campaign + bid modifiers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignBidModifierOperation]): + Required. The list of operations to perform + on individual campaign bid modifiers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignBidModifierOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignBidModifierOperation(proto.Message): + r"""A single operation (create, remove, update) on a campaign bid + modifier. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignBidModifier): + Create operation: No resource name is + expected for the new campaign bid modifier. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignBidModifier): + Update operation: The campaign bid modifier + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + bid modifier is expected, in this format: + + ``customers/{customer_id}/CampaignBidModifiers/{campaign_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_bid_modifier.CampaignBidModifier, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_bid_modifier.CampaignBidModifier, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignBidModifiersResponse(proto.Message): + r"""Response message for campaign bid modifiers mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignBidModifierResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignBidModifierResult", + ) + + +class MutateCampaignBidModifierResult(proto.Message): + r"""The result for the criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_bid_modifier (google.ads.googleads.v12.resources.types.CampaignBidModifier): + The mutated campaign bid modifier with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_bid_modifier = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_bid_modifier.CampaignBidModifier, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_budget_service.py b/google/ads/googleads/v12/services/types/campaign_budget_service.py new file mode 100644 index 000000000..672e6b094 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_budget_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_budget as gagr_campaign_budget, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignBudgetsRequest", + "CampaignBudgetOperation", + "MutateCampaignBudgetsResponse", + "MutateCampaignBudgetResult", + }, +) + + +class MutateCampaignBudgetsRequest(proto.Message): + r"""Request message for + [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v12.services.CampaignBudgetService.MutateCampaignBudgets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign budgets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignBudgetOperation]): + Required. The list of operations to perform + on individual campaign budgets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignBudgetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignBudgetOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + budget. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignBudget): + Create operation: No resource name is + expected for the new budget. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignBudget): + Update operation: The campaign budget is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed budget is + expected, in this format: + + ``customers/{customer_id}/campaignBudgets/{budget_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_budget.CampaignBudget, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_budget.CampaignBudget, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignBudgetsResponse(proto.Message): + r"""Response message for campaign budget mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignBudgetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignBudgetResult", + ) + + +class MutateCampaignBudgetResult(proto.Message): + r"""The result for the campaign budget mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_budget (google.ads.googleads.v12.resources.types.CampaignBudget): + The mutated campaign budget with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_budget = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign_budget.CampaignBudget, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_conversion_goal_service.py b/google/ads/googleads/v12/services/types/campaign_conversion_goal_service.py new file mode 100644 index 000000000..b50bd7b7b --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_conversion_goal_service.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import campaign_conversion_goal +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignConversionGoalsRequest", + "CampaignConversionGoalOperation", + "MutateCampaignConversionGoalsResponse", + "MutateCampaignConversionGoalResult", + }, +) + + +class MutateCampaignConversionGoalsRequest(proto.Message): + r"""Request message for + [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v12.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign conversion goals are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignConversionGoalOperation]): + Required. The list of operations to perform + on individual campaign conversion goal. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignConversionGoalOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class CampaignConversionGoalOperation(proto.Message): + r"""A single operation (update) on a campaign conversion goal. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.CampaignConversionGoal): + Update operation: The customer conversion + goal is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=campaign_conversion_goal.CampaignConversionGoal, + ) + + +class MutateCampaignConversionGoalsResponse(proto.Message): + r"""Response message for a campaign conversion goal mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignConversionGoalResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCampaignConversionGoalResult", + ) + + +class MutateCampaignConversionGoalResult(proto.Message): + r"""The result for the campaign conversion goal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_criterion_service.py b/google/ads/googleads/v12/services/types/campaign_criterion_service.py new file mode 100644 index 000000000..28c142947 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_criterion_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_criterion as gagr_campaign_criterion, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignCriteriaRequest", + "CampaignCriterionOperation", + "MutateCampaignCriteriaResponse", + "MutateCampaignCriterionResult", + }, +) + + +class MutateCampaignCriteriaRequest(proto.Message): + r"""Request message for + [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v12.services.CampaignCriterionService.MutateCampaignCriteria]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + criteria are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignCriterionOperation]): + Required. The list of operations to perform + on individual criteria. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignCriterionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignCriterionOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + criterion. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignCriterion): + Create operation: No resource name is + expected for the new criterion. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignCriterion): + Update operation: The criterion is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed criterion + is expected, in this format: + + ``customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_criterion.CampaignCriterion, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_criterion.CampaignCriterion, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignCriteriaResponse(proto.Message): + r"""Response message for campaign criterion mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignCriterionResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignCriterionResult", + ) + + +class MutateCampaignCriterionResult(proto.Message): + r"""The result for the criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_criterion (google.ads.googleads.v12.resources.types.CampaignCriterion): + The mutated campaign criterion with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_criterion = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_criterion.CampaignCriterion, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_customizer_service.py b/google/ads/googleads/v12/services/types/campaign_customizer_service.py new file mode 100644 index 000000000..0b01819cb --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_customizer_service.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_customizer as gagr_campaign_customizer, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignCustomizersRequest", + "CampaignCustomizerOperation", + "MutateCampaignCustomizersResponse", + "MutateCampaignCustomizerResult", + }, +) + + +class MutateCampaignCustomizersRequest(proto.Message): + r"""Request message for + [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v12.services.CampaignCustomizerService.MutateCampaignCustomizers]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign customizers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignCustomizerOperation]): + Required. The list of operations to perform + on individual campaign customizers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignCustomizerOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignCustomizerOperation(proto.Message): + r"""A single operation (create, remove) on an customizer + attribute. + + 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: + create (google.ads.googleads.v12.resources.types.CampaignCustomizer): + Create operation: No resource name is + expected for the new campaign customizer + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + customizer is expected, in this format: + ``customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_customizer.CampaignCustomizer, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCampaignCustomizersResponse(proto.Message): + r"""Response message for an campaign customizer mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignCustomizerResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCampaignCustomizerResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateCampaignCustomizerResult(proto.Message): + r"""The result for the campaign customizer mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_customizer (google.ads.googleads.v12.resources.types.CampaignCustomizer): + The mutated CampaignCustomizer with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_customizer = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_customizer.CampaignCustomizer, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_draft_service.py b/google/ads/googleads/v12/services/types/campaign_draft_service.py new file mode 100644 index 000000000..89279a127 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_draft_service.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_draft as gagr_campaign_draft, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignDraftsRequest", + "PromoteCampaignDraftRequest", + "CampaignDraftOperation", + "MutateCampaignDraftsResponse", + "MutateCampaignDraftResult", + "ListCampaignDraftAsyncErrorsRequest", + "ListCampaignDraftAsyncErrorsResponse", + }, +) + + +class MutateCampaignDraftsRequest(proto.Message): + r"""Request message for + [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v12.services.CampaignDraftService.MutateCampaignDrafts]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign drafts are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignDraftOperation]): + Required. The list of operations to perform + on individual campaign drafts. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignDraftOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class PromoteCampaignDraftRequest(proto.Message): + r"""Request message for + [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v12.services.CampaignDraftService.PromoteCampaignDraft]. + + Attributes: + campaign_draft (str): + Required. The resource name of the campaign + draft to promote. + validate_only (bool): + If true, the request is validated but no Long + Running Operation is created. Only errors are + returned. + """ + + campaign_draft = proto.Field(proto.STRING, number=1,) + validate_only = proto.Field(proto.BOOL, number=2,) + + +class CampaignDraftOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + draft. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignDraft): + Create operation: No resource name is + expected for the new campaign draft. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignDraft): + Update operation: The campaign draft is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: The campaign draft is expected to have a + valid resource name, in this format: + + ``customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_draft.CampaignDraft, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_draft.CampaignDraft, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignDraftsResponse(proto.Message): + r"""Response message for campaign draft mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignDraftResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignDraftResult", + ) + + +class MutateCampaignDraftResult(proto.Message): + r"""The result for the campaign draft mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_draft (google.ads.googleads.v12.resources.types.CampaignDraft): + The mutated campaign draft with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_draft = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign_draft.CampaignDraft, + ) + + +class ListCampaignDraftAsyncErrorsRequest(proto.Message): + r"""Request message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + + Attributes: + resource_name (str): + Required. The name of the campaign draft from + which to retrieve the async errors. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. Use the value obtained + from ``next_page_token`` in the previous response in order + to request the next page of results. + page_size (int): + Number of elements to retrieve in a single + page. When a page request is too large, the + server may decide to further limit the number of + returned resources. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + page_token = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + + +class ListCampaignDraftAsyncErrorsResponse(proto.Message): + r"""Response message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v12.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + + Attributes: + errors (Sequence[google.rpc.status_pb2.Status]): + Details of the errors when performing the + asynchronous operation. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + """ + + @property + def raw_page(self): + return self + + errors = proto.RepeatedField( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_extension_setting_service.py b/google/ads/googleads/v12/services/types/campaign_extension_setting_service.py new file mode 100644 index 000000000..a975bccd7 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_extension_setting_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_extension_setting as gagr_campaign_extension_setting, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignExtensionSettingsRequest", + "CampaignExtensionSettingOperation", + "MutateCampaignExtensionSettingsResponse", + "MutateCampaignExtensionSettingResult", + }, +) + + +class MutateCampaignExtensionSettingsRequest(proto.Message): + r"""Request message for + [CampaignExtensionSettingService.MutateCampaignExtensionSettings][google.ads.googleads.v12.services.CampaignExtensionSettingService.MutateCampaignExtensionSettings]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign extension settings are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignExtensionSettingOperation]): + Required. The list of operations to perform + on individual campaign extension settings. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignExtensionSettingOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignExtensionSettingOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + extension setting. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignExtensionSetting): + Create operation: No resource name is + expected for the new campaign extension setting. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignExtensionSetting): + Update operation: The campaign extension + setting is expected to have a valid resource + name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + extension setting is expected, in this format: + + ``customers/{customer_id}/campaignExtensionSettings/{campaign_id}~{extension_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_extension_setting.CampaignExtensionSetting, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_extension_setting.CampaignExtensionSetting, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignExtensionSettingsResponse(proto.Message): + r"""Response message for a campaign extension setting mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignExtensionSettingResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignExtensionSettingResult", + ) + + +class MutateCampaignExtensionSettingResult(proto.Message): + r"""The result for the campaign extension setting mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_extension_setting (google.ads.googleads.v12.resources.types.CampaignExtensionSetting): + The mutated campaign extension setting with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_extension_setting = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_extension_setting.CampaignExtensionSetting, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_feed_service.py b/google/ads/googleads/v12/services/types/campaign_feed_service.py new file mode 100644 index 000000000..2e7da6f9d --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_feed_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_feed as gagr_campaign_feed, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignFeedsRequest", + "CampaignFeedOperation", + "MutateCampaignFeedsResponse", + "MutateCampaignFeedResult", + }, +) + + +class MutateCampaignFeedsRequest(proto.Message): + r"""Request message for + [CampaignFeedService.MutateCampaignFeeds][google.ads.googleads.v12.services.CampaignFeedService.MutateCampaignFeeds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign feeds are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignFeedOperation]): + Required. The list of operations to perform + on individual campaign feeds. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignFeedOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignFeedOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + feed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignFeed): + Create operation: No resource name is + expected for the new campaign feed. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignFeed): + Update operation: The campaign feed is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + feed is expected, in this format: + + ``customers/{customer_id}/campaignFeeds/{campaign_id}~{feed_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_feed.CampaignFeed, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_feed.CampaignFeed, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignFeedsResponse(proto.Message): + r"""Response message for a campaign feed mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignFeedResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignFeedResult", + ) + + +class MutateCampaignFeedResult(proto.Message): + r"""The result for the campaign feed mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_feed (google.ads.googleads.v12.resources.types.CampaignFeed): + The mutated campaign feed with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_feed = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign_feed.CampaignFeed, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_group_service.py b/google/ads/googleads/v12/services/types/campaign_group_service.py new file mode 100644 index 000000000..9d4116acb --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_group_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_group as gagr_campaign_group, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignGroupsRequest", + "CampaignGroupOperation", + "MutateCampaignGroupsResponse", + "MutateCampaignGroupResult", + }, +) + + +class MutateCampaignGroupsRequest(proto.Message): + r"""Request message for + [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v12.services.CampaignGroupService.MutateCampaignGroups]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign groups are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignGroupOperation]): + Required. The list of operations to perform + on individual campaign groups. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignGroupOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignGroupOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign + group. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CampaignGroup): + Create operation: No resource name is + expected for the new campaign group. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CampaignGroup): + Update operation: The campaign group is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + group is expected, in this format: + + ``customers/{customer_id}/campaignGroups/{campaign_group_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_group.CampaignGroup, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign_group.CampaignGroup, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignGroupsResponse(proto.Message): + r"""Response message for campaign group mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignGroupResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignGroupResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + + +class MutateCampaignGroupResult(proto.Message): + r"""The result for the campaign group mutate. + + Attributes: + resource_name (str): + Required. Returned for successful operations. + campaign_group (google.ads.googleads.v12.resources.types.CampaignGroup): + The mutated campaign group with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_group = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign_group.CampaignGroup, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_label_service.py b/google/ads/googleads/v12/services/types/campaign_label_service.py new file mode 100644 index 000000000..9ae957920 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_label_service.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import campaign_label +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignLabelsRequest", + "CampaignLabelOperation", + "MutateCampaignLabelsResponse", + "MutateCampaignLabelResult", + }, +) + + +class MutateCampaignLabelsRequest(proto.Message): + r"""Request message for + [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v12.services.CampaignLabelService.MutateCampaignLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose + campaign-label relationships are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignLabelOperation]): + Required. The list of operations to perform + on campaign-label relationships. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignLabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class CampaignLabelOperation(proto.Message): + r"""A single operation (create, remove) on a campaign-label + relationship. + + 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: + create (google.ads.googleads.v12.resources.types.CampaignLabel): + Create operation: No resource name is + expected for the new campaign-label + relationship. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the campaign-label + relationship being removed, in this format: + + ``customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=campaign_label.CampaignLabel, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCampaignLabelsResponse(proto.Message): + r"""Response message for a campaign labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignLabelResult", + ) + + +class MutateCampaignLabelResult(proto.Message): + r"""The result for a campaign label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_service.py b/google/ads/googleads/v12/services/types/campaign_service.py new file mode 100644 index 000000000..061bc7ab5 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_service.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import campaign as gagr_campaign +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignsRequest", + "CampaignOperation", + "MutateCampaignsResponse", + "MutateCampaignResult", + }, +) + + +class MutateCampaignsRequest(proto.Message): + r"""Request message for + [CampaignService.MutateCampaigns][google.ads.googleads.v12.services.CampaignService.MutateCampaigns]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaigns are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignOperation]): + Required. The list of operations to perform + on individual campaigns. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignOperation(proto.Message): + r"""A single operation (create, update, remove) on a campaign. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Campaign): + Create operation: No resource name is + expected for the new campaign. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Campaign): + Update operation: The campaign is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + is expected, in this format: + + ``customers/{customer_id}/campaigns/{campaign_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign.Campaign, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_campaign.Campaign, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignsResponse(proto.Message): + r"""Response message for campaign mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignResult", + ) + + +class MutateCampaignResult(proto.Message): + r"""The result for the campaign mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign (google.ads.googleads.v12.resources.types.Campaign): + The mutated campaign with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign.Campaign, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/campaign_shared_set_service.py b/google/ads/googleads/v12/services/types/campaign_shared_set_service.py new file mode 100644 index 000000000..bc049efb4 --- /dev/null +++ b/google/ads/googleads/v12/services/types/campaign_shared_set_service.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + campaign_shared_set as gagr_campaign_shared_set, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCampaignSharedSetsRequest", + "CampaignSharedSetOperation", + "MutateCampaignSharedSetsResponse", + "MutateCampaignSharedSetResult", + }, +) + + +class MutateCampaignSharedSetsRequest(proto.Message): + r"""Request message for + [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v12.services.CampaignSharedSetService.MutateCampaignSharedSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign shared sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CampaignSharedSetOperation]): + Required. The list of operations to perform + on individual campaign shared sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignSharedSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CampaignSharedSetOperation(proto.Message): + r"""A single operation (create, remove) on an campaign shared + set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.CampaignSharedSet): + Create operation: No resource name is + expected for the new campaign shared set. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed campaign + shared set is expected, in this format: + + ``customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_campaign_shared_set.CampaignSharedSet, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCampaignSharedSetsResponse(proto.Message): + r"""Response message for a campaign shared set mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCampaignSharedSetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCampaignSharedSetResult", + ) + + +class MutateCampaignSharedSetResult(proto.Message): + r"""The result for the campaign shared set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + campaign_shared_set (google.ads.googleads.v12.resources.types.CampaignSharedSet): + The mutated campaign shared set with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_shared_set = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_campaign_shared_set.CampaignSharedSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_action_service.py b/google/ads/googleads/v12/services/types/conversion_action_service.py new file mode 100644 index 000000000..45a2594a0 --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_action_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + conversion_action as gagr_conversion_action, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateConversionActionsRequest", + "ConversionActionOperation", + "MutateConversionActionsResponse", + "MutateConversionActionResult", + }, +) + + +class MutateConversionActionsRequest(proto.Message): + r"""Request message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v12.services.ConversionActionService.MutateConversionActions]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + conversion actions are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionActionOperation]): + Required. The list of operations to perform + on individual conversion actions. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionActionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ConversionActionOperation(proto.Message): + r"""A single operation (create, update, remove) on a conversion + 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: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ConversionAction): + Create operation: No resource name is + expected for the new conversion action. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ConversionAction): + Update operation: The conversion action is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed conversion + action is expected, in this format: + + ``customers/{customer_id}/conversionActions/{conversion_action_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_conversion_action.ConversionAction, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_conversion_action.ConversionAction, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateConversionActionsResponse(proto.Message): + r"""Response message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v12.services.ConversionActionService.MutateConversionActions]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateConversionActionResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateConversionActionResult", + ) + + +class MutateConversionActionResult(proto.Message): + r"""The result for the conversion action mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + conversion_action (google.ads.googleads.v12.resources.types.ConversionAction): + The mutated conversion action with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + conversion_action = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_conversion_action.ConversionAction, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_adjustment_upload_service.py b/google/ads/googleads/v12/services/types/conversion_adjustment_upload_service.py new file mode 100644 index 000000000..caef89afc --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_adjustment_upload_service.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import offline_user_data +from google.ads.googleads.v12.enums.types import conversion_adjustment_type +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "UploadConversionAdjustmentsRequest", + "UploadConversionAdjustmentsResponse", + "ConversionAdjustment", + "RestatementValue", + "GclidDateTimePair", + "ConversionAdjustmentResult", + }, +) + + +class UploadConversionAdjustmentsRequest(proto.Message): + r"""Request message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v12.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + + Attributes: + customer_id (str): + Required. The ID of the customer performing + the upload. + conversion_adjustments (Sequence[google.ads.googleads.v12.services.types.ConversionAdjustment]): + Required. The conversion adjustments that are + being uploaded. + partial_failure (bool): + Required. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. This should always be set to + true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + conversion_adjustments = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionAdjustment", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class UploadConversionAdjustmentsResponse(proto.Message): + r"""Response message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v12.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to conversion adjustment + failures in the partial failure mode. Returned + when all errors occur inside the adjustments. If + any errors occur outside the adjustments (for + example, auth errors), we return an RPC level + error. See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + results (Sequence[google.ads.googleads.v12.services.types.ConversionAdjustmentResult]): + Returned for successfully processed conversion adjustments. + Proto will be empty for rows that received an error. Results + are not returned when validate_only is true. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionAdjustmentResult", + ) + + +class ConversionAdjustment(proto.Message): + r"""A conversion adjustment. + + Attributes: + gclid_date_time_pair (google.ads.googleads.v12.services.types.GclidDateTimePair): + For adjustments, uniquely identifies a conversion that was + reported without an order ID specified. If the + adjustment_type is ENHANCEMENT, this value is optional but + may be set in addition to the order_id. + order_id (str): + The order ID of the conversion to be + adjusted. If the conversion was reported with an + order ID specified, that order ID must be used + as the identifier here. The order ID is required + for enhancements. + + This field is a member of `oneof`_ ``_order_id``. + conversion_action (str): + Resource name of the conversion action + associated with this conversion adjustment. + Note: Although this resource name consists of a + customer id and a conversion action id, + validation will ignore the customer id and use + the conversion action id as the sole identifier + of the conversion action. + + This field is a member of `oneof`_ ``_conversion_action``. + adjustment_date_time (str): + The date time at which the adjustment occurred. Must be + after the conversion_date_time. The timezone must be + specified. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for + example, "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_adjustment_date_time``. + adjustment_type (google.ads.googleads.v12.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): + The adjustment type. + restatement_value (google.ads.googleads.v12.services.types.RestatementValue): + Information needed to restate the + conversion's value. Required for restatements. + Should not be supplied for retractions. An error + will be returned if provided for a retraction. + NOTE: If you want to upload a second restatement + with a different adjusted value, it must have a + new, more recent, adjustment occurrence time. + Otherwise, it will be treated as a duplicate of + the previous restatement and ignored. + user_identifiers (Sequence[google.ads.googleads.v12.common.types.UserIdentifier]): + The user identifiers to enhance the original + conversion. ConversionAdjustmentUploadService + only accepts user identifiers in enhancements. + The maximum number of user identifiers for each + enhancement is 5. + user_agent (str): + The user agent to enhance the original conversion. This can + be found in your user's HTTP request header when they + convert on your web page. Example, "Mozilla/5.0 (iPhone; CPU + iPhone OS 12_2 like Mac OS X)". User agent can only be + specified in enhancements with user identifiers. This should + match the user agent of the request that sent the original + conversion so the conversion and its enhancement are either + both attributed as same-device or both attributed as + cross-device. + + This field is a member of `oneof`_ ``_user_agent``. + """ + + gclid_date_time_pair = proto.Field( + proto.MESSAGE, number=12, message="GclidDateTimePair", + ) + order_id = proto.Field(proto.STRING, number=13, optional=True,) + conversion_action = proto.Field(proto.STRING, number=8, optional=True,) + adjustment_date_time = proto.Field(proto.STRING, number=9, optional=True,) + adjustment_type = proto.Field( + proto.ENUM, + number=5, + enum=conversion_adjustment_type.ConversionAdjustmentTypeEnum.ConversionAdjustmentType, + ) + restatement_value = proto.Field( + proto.MESSAGE, number=6, message="RestatementValue", + ) + user_identifiers = proto.RepeatedField( + proto.MESSAGE, number=10, message=offline_user_data.UserIdentifier, + ) + user_agent = proto.Field(proto.STRING, number=11, optional=True,) + + +class RestatementValue(proto.Message): + r"""Contains information needed to restate a conversion's value. + + Attributes: + adjusted_value (float): + The restated conversion value. This is the + value of the conversion after restatement. For + example, to change the value of a conversion + from 100 to 70, an adjusted value of 70 should + be reported. NOTE: If you want to upload a + second restatement with a different adjusted + value, it must have a new, more recent, + adjustment occurrence time. Otherwise, it will + be treated as a duplicate of the previous + restatement and ignored. + + This field is a member of `oneof`_ ``_adjusted_value``. + currency_code (str): + The currency of the restated value. If not + provided, then the default currency from the + conversion action is used, and if that is not + set then the account currency is used. This is + the ISO 4217 3-character currency code for + example, USD or EUR. + + This field is a member of `oneof`_ ``_currency_code``. + """ + + adjusted_value = proto.Field(proto.DOUBLE, number=3, optional=True,) + currency_code = proto.Field(proto.STRING, number=4, optional=True,) + + +class GclidDateTimePair(proto.Message): + r"""Uniquely identifies a conversion that was reported without an + order ID specified. + + Attributes: + gclid (str): + Google click ID (gclid) associated with the + original conversion for this adjustment. + + This field is a member of `oneof`_ ``_gclid``. + conversion_date_time (str): + The date time at which the original conversion for this + adjustment occurred. The timezone must be specified. The + format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_conversion_date_time``. + """ + + gclid = proto.Field(proto.STRING, number=3, optional=True,) + conversion_date_time = proto.Field(proto.STRING, number=4, optional=True,) + + +class ConversionAdjustmentResult(proto.Message): + r"""Information identifying a successfully processed + ConversionAdjustment. + + Attributes: + gclid_date_time_pair (google.ads.googleads.v12.services.types.GclidDateTimePair): + The gclid and conversion date time of the + conversion. + order_id (str): + The order ID of the conversion to be + adjusted. + conversion_action (str): + Resource name of the conversion action + associated with this conversion adjustment. + + This field is a member of `oneof`_ ``_conversion_action``. + adjustment_date_time (str): + The date time at which the adjustment occurred. The format + is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + 12:32:45-08:00". + + This field is a member of `oneof`_ ``_adjustment_date_time``. + adjustment_type (google.ads.googleads.v12.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): + The adjustment type. + """ + + gclid_date_time_pair = proto.Field( + proto.MESSAGE, number=9, message="GclidDateTimePair", + ) + order_id = proto.Field(proto.STRING, number=10,) + conversion_action = proto.Field(proto.STRING, number=7, optional=True,) + adjustment_date_time = proto.Field(proto.STRING, number=8, optional=True,) + adjustment_type = proto.Field( + proto.ENUM, + number=5, + enum=conversion_adjustment_type.ConversionAdjustmentTypeEnum.ConversionAdjustmentType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_custom_variable_service.py b/google/ads/googleads/v12/services/types/conversion_custom_variable_service.py new file mode 100644 index 000000000..4a9ee2b0c --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_custom_variable_service.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + conversion_custom_variable as gagr_conversion_custom_variable, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateConversionCustomVariablesRequest", + "ConversionCustomVariableOperation", + "MutateConversionCustomVariablesResponse", + "MutateConversionCustomVariableResult", + }, +) + + +class MutateConversionCustomVariablesRequest(proto.Message): + r"""Request message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v12.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + conversion custom variables are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionCustomVariableOperation]): + Required. The list of operations to perform + on individual conversion custom variables. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionCustomVariableOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ConversionCustomVariableOperation(proto.Message): + r"""A single operation (create, update) on a conversion custom + variable. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ConversionCustomVariable): + Create operation: No resource name is + expected for the new conversion custom variable. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ConversionCustomVariable): + Update operation: The conversion custom + variable is expected to have a valid resource + name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_conversion_custom_variable.ConversionCustomVariable, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_conversion_custom_variable.ConversionCustomVariable, + ) + + +class MutateConversionCustomVariablesResponse(proto.Message): + r"""Response message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v12.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateConversionCustomVariableResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateConversionCustomVariableResult", + ) + + +class MutateConversionCustomVariableResult(proto.Message): + r"""The result for the conversion custom variable mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + conversion_custom_variable (google.ads.googleads.v12.resources.types.ConversionCustomVariable): + The mutated conversion custom variable with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + conversion_custom_variable = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_conversion_custom_variable.ConversionCustomVariable, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_goal_campaign_config_service.py b/google/ads/googleads/v12/services/types/conversion_goal_campaign_config_service.py new file mode 100644 index 000000000..200357e01 --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_goal_campaign_config_service.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + conversion_goal_campaign_config as gagr_conversion_goal_campaign_config, +) +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateConversionGoalCampaignConfigsRequest", + "ConversionGoalCampaignConfigOperation", + "MutateConversionGoalCampaignConfigsResponse", + "MutateConversionGoalCampaignConfigResult", + }, +) + + +class MutateConversionGoalCampaignConfigsRequest(proto.Message): + r"""Request message for + [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfig][]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose custom + conversion goals are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionGoalCampaignConfigOperation]): + Required. The list of operations to perform + on individual conversion goal campaign config. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="ConversionGoalCampaignConfigOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ConversionGoalCampaignConfigOperation(proto.Message): + r"""A single operation (update) on a conversion goal campaign + config. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.ConversionGoalCampaignConfig): + Update operation: The conversion goal + campaign config is expected to have a valid + resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_conversion_goal_campaign_config.ConversionGoalCampaignConfig, + ) + + +class MutateConversionGoalCampaignConfigsResponse(proto.Message): + r"""Response message for a conversion goal campaign config + mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateConversionGoalCampaignConfigResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="MutateConversionGoalCampaignConfigResult", + ) + + +class MutateConversionGoalCampaignConfigResult(proto.Message): + r"""The result for the conversion goal campaign config mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + conversion_goal_campaign_config (google.ads.googleads.v12.resources.types.ConversionGoalCampaignConfig): + The mutated ConversionGoalCampaignConfig with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + conversion_goal_campaign_config = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_conversion_goal_campaign_config.ConversionGoalCampaignConfig, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_upload_service.py b/google/ads/googleads/v12/services/types/conversion_upload_service.py new file mode 100644 index 000000000..b46bbc1ee --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_upload_service.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import offline_user_data +from google.ads.googleads.v12.enums.types import conversion_environment_enum +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "UploadClickConversionsRequest", + "UploadClickConversionsResponse", + "UploadCallConversionsRequest", + "UploadCallConversionsResponse", + "ClickConversion", + "CallConversion", + "ExternalAttributionData", + "ClickConversionResult", + "CallConversionResult", + "CustomVariable", + "CartData", + }, +) + + +class UploadClickConversionsRequest(proto.Message): + r"""Request message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadClickConversions]. + + Attributes: + customer_id (str): + Required. The ID of the customer performing + the upload. + conversions (Sequence[google.ads.googleads.v12.services.types.ClickConversion]): + Required. The conversions that are being + uploaded. + partial_failure (bool): + Required. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. This should always be set to + true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + debug_enabled (bool): + If true, the API will perform all upload checks and return + errors if any are found. If false, it will perform only + basic input validation, skip subsequent upload checks, and + return success even if no click was found for the provided + ``user_identifiers``. + + This setting only affects Enhanced conversions for leads + uploads that use ``user_identifiers`` instead of ``GCLID``, + ``GBRAID``, or ``WBRAID``. When uploading enhanced + conversions for leads, you should upload all conversion + events to the API, including those that may not come from + Google Ads campaigns. The upload of an event that is not + from a Google Ads campaign will result in a + ``CLICK_NOT_FOUND`` error if this field is set to ``true``. + Since these errors are expected for such events, set this + field to ``false`` so you can confirm your uploads are + properly formatted but ignore ``CLICK_NOT_FOUND`` errors + from all of the conversions that are not from a Google Ads + campaign. This will allow you to focus only on errors that + you can address. + + Default is false. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + conversions = proto.RepeatedField( + proto.MESSAGE, number=2, message="ClickConversion", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + debug_enabled = proto.Field(proto.BOOL, number=5,) + + +class UploadClickConversionsResponse(proto.Message): + r"""Response message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadClickConversions]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to conversion failures in + the partial failure mode. Returned when all + errors occur inside the conversions. If any + errors occur outside the conversions (for + example, auth errors), we return an RPC level + error. See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + results (Sequence[google.ads.googleads.v12.services.types.ClickConversionResult]): + Returned for successfully processed conversions. Proto will + be empty for rows that received an error. Results are not + returned when validate_only is true. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="ClickConversionResult", + ) + + +class UploadCallConversionsRequest(proto.Message): + r"""Request message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadCallConversions]. + + Attributes: + customer_id (str): + Required. The ID of the customer performing + the upload. + conversions (Sequence[google.ads.googleads.v12.services.types.CallConversion]): + Required. The conversions that are being + uploaded. + partial_failure (bool): + Required. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. This should always be set to + true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + conversions = proto.RepeatedField( + proto.MESSAGE, number=2, message="CallConversion", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class UploadCallConversionsResponse(proto.Message): + r"""Response message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v12.services.ConversionUploadService.UploadCallConversions]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to conversion failures in + the partial failure mode. Returned when all + errors occur inside the conversions. If any + errors occur outside the conversions (for + example, auth errors), we return an RPC level + error. See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + results (Sequence[google.ads.googleads.v12.services.types.CallConversionResult]): + Returned for successfully processed conversions. Proto will + be empty for rows that received an error. Results are not + returned when validate_only is true. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="CallConversionResult", + ) + + +class ClickConversion(proto.Message): + r"""A click conversion. + + Attributes: + gclid (str): + The Google click ID (gclid) associated with + this conversion. + + This field is a member of `oneof`_ ``_gclid``. + gbraid (str): + The click identifier for clicks associated + with app conversions and originating from iOS + devices starting with iOS14. + wbraid (str): + The click identifier for clicks associated + with web conversions and originating from iOS + devices starting with iOS14. + conversion_action (str): + Resource name of the conversion action + associated with this conversion. Note: Although + this resource name consists of a customer id and + a conversion action id, validation will ignore + the customer id and use the conversion action id + as the sole identifier of the conversion action. + + This field is a member of `oneof`_ ``_conversion_action``. + conversion_date_time (str): + The date time at which the conversion occurred. Must be + after the click time. The timezone must be specified. The + format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_conversion_date_time``. + conversion_value (float): + The value of the conversion for the + advertiser. + + This field is a member of `oneof`_ ``_conversion_value``. + currency_code (str): + Currency associated with the conversion + value. This is the ISO 4217 3-character currency + code. For example: USD, EUR. + + This field is a member of `oneof`_ ``_currency_code``. + order_id (str): + The order ID associated with the conversion. + An order id can only be used for one conversion + per conversion action. + + This field is a member of `oneof`_ ``_order_id``. + external_attribution_data (google.ads.googleads.v12.services.types.ExternalAttributionData): + Additional data about externally attributed + conversions. This field is required for + conversions with an externally attributed + conversion action, but should not be set + otherwise. + custom_variables (Sequence[google.ads.googleads.v12.services.types.CustomVariable]): + The custom variables associated with this + conversion. + cart_data (google.ads.googleads.v12.services.types.CartData): + The cart data associated with this + conversion. + user_identifiers (Sequence[google.ads.googleads.v12.common.types.UserIdentifier]): + The user identifiers associated with this conversion. Only + hashed_email and hashed_phone_number are supported for + conversion uploads. The maximum number of user identifiers + for each conversion is 5. + conversion_environment (google.ads.googleads.v12.enums.types.ConversionEnvironmentEnum.ConversionEnvironment): + The environment this conversion was recorded + on, for example, App or Web. + """ + + gclid = proto.Field(proto.STRING, number=9, optional=True,) + gbraid = proto.Field(proto.STRING, number=18,) + wbraid = proto.Field(proto.STRING, number=19,) + conversion_action = proto.Field(proto.STRING, number=10, optional=True,) + conversion_date_time = proto.Field(proto.STRING, number=11, optional=True,) + conversion_value = proto.Field(proto.DOUBLE, number=12, optional=True,) + currency_code = proto.Field(proto.STRING, number=13, optional=True,) + order_id = proto.Field(proto.STRING, number=14, optional=True,) + external_attribution_data = proto.Field( + proto.MESSAGE, number=7, message="ExternalAttributionData", + ) + custom_variables = proto.RepeatedField( + proto.MESSAGE, number=15, message="CustomVariable", + ) + cart_data = proto.Field(proto.MESSAGE, number=16, message="CartData",) + user_identifiers = proto.RepeatedField( + proto.MESSAGE, number=17, message=offline_user_data.UserIdentifier, + ) + conversion_environment = proto.Field( + proto.ENUM, + number=20, + enum=conversion_environment_enum.ConversionEnvironmentEnum.ConversionEnvironment, + ) + + +class CallConversion(proto.Message): + r"""A call conversion. + + Attributes: + caller_id (str): + The caller id from which this call was + placed. Caller id is expected to be in E.164 + format with preceding '+' sign, for example, + "+16502531234". + + This field is a member of `oneof`_ ``_caller_id``. + call_start_date_time (str): + The date time at which the call occurred. The timezone must + be specified. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", + for example, "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_call_start_date_time``. + conversion_action (str): + Resource name of the conversion action + associated with this conversion. Note: Although + this resource name consists of a customer id and + a conversion action id, validation will ignore + the customer id and use the conversion action id + as the sole identifier of the conversion action. + + This field is a member of `oneof`_ ``_conversion_action``. + conversion_date_time (str): + The date time at which the conversion occurred. Must be + after the call time. The timezone must be specified. The + format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_conversion_date_time``. + conversion_value (float): + The value of the conversion for the + advertiser. + + This field is a member of `oneof`_ ``_conversion_value``. + currency_code (str): + Currency associated with the conversion + value. This is the ISO 4217 3-character currency + code. For example: USD, EUR. + + This field is a member of `oneof`_ ``_currency_code``. + custom_variables (Sequence[google.ads.googleads.v12.services.types.CustomVariable]): + The custom variables associated with this + conversion. + """ + + caller_id = proto.Field(proto.STRING, number=7, optional=True,) + call_start_date_time = proto.Field(proto.STRING, number=8, optional=True,) + conversion_action = proto.Field(proto.STRING, number=9, optional=True,) + conversion_date_time = proto.Field(proto.STRING, number=10, optional=True,) + conversion_value = proto.Field(proto.DOUBLE, number=11, optional=True,) + currency_code = proto.Field(proto.STRING, number=12, optional=True,) + custom_variables = proto.RepeatedField( + proto.MESSAGE, number=13, message="CustomVariable", + ) + + +class ExternalAttributionData(proto.Message): + r"""Contains additional information about externally attributed + conversions. + + Attributes: + external_attribution_credit (float): + Represents the fraction of the conversion + that is attributed to the Google Ads click. + + This field is a member of `oneof`_ ``_external_attribution_credit``. + external_attribution_model (str): + Specifies the attribution model name. + + This field is a member of `oneof`_ ``_external_attribution_model``. + """ + + external_attribution_credit = proto.Field( + proto.DOUBLE, number=3, optional=True, + ) + external_attribution_model = proto.Field( + proto.STRING, number=4, optional=True, + ) + + +class ClickConversionResult(proto.Message): + r"""Identifying information for a successfully processed + ClickConversion. + + Attributes: + gclid (str): + The Google Click ID (gclid) associated with + this conversion. + + This field is a member of `oneof`_ ``_gclid``. + gbraid (str): + The click identifier for clicks associated + with app conversions and originating from iOS + devices starting with iOS14. + wbraid (str): + The click identifier for clicks associated + with web conversions and originating from iOS + devices starting with iOS14. + conversion_action (str): + Resource name of the conversion action + associated with this conversion. + + This field is a member of `oneof`_ ``_conversion_action``. + conversion_date_time (str): + The date time at which the conversion occurred. The format + is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + 12:32:45-08:00". + + This field is a member of `oneof`_ ``_conversion_date_time``. + user_identifiers (Sequence[google.ads.googleads.v12.common.types.UserIdentifier]): + The user identifiers associated with this conversion. Only + hashed_email and hashed_phone_number are supported for + conversion uploads. The maximum number of user identifiers + for each conversion is 5. + """ + + gclid = proto.Field(proto.STRING, number=4, optional=True,) + gbraid = proto.Field(proto.STRING, number=8,) + wbraid = proto.Field(proto.STRING, number=9,) + conversion_action = proto.Field(proto.STRING, number=5, optional=True,) + conversion_date_time = proto.Field(proto.STRING, number=6, optional=True,) + user_identifiers = proto.RepeatedField( + proto.MESSAGE, number=7, message=offline_user_data.UserIdentifier, + ) + + +class CallConversionResult(proto.Message): + r"""Identifying information for a successfully processed + CallConversionUpload. + + Attributes: + caller_id (str): + The caller id from which this call was + placed. Caller id is expected to be in E.164 + format with preceding '+' sign. + + This field is a member of `oneof`_ ``_caller_id``. + call_start_date_time (str): + The date time at which the call occurred. The format is + "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + 12:32:45-08:00". + + This field is a member of `oneof`_ ``_call_start_date_time``. + conversion_action (str): + Resource name of the conversion action + associated with this conversion. + + This field is a member of `oneof`_ ``_conversion_action``. + conversion_date_time (str): + The date time at which the conversion occurred. The format + is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + 12:32:45-08:00". + + This field is a member of `oneof`_ ``_conversion_date_time``. + """ + + caller_id = proto.Field(proto.STRING, number=5, optional=True,) + call_start_date_time = proto.Field(proto.STRING, number=6, optional=True,) + conversion_action = proto.Field(proto.STRING, number=7, optional=True,) + conversion_date_time = proto.Field(proto.STRING, number=8, optional=True,) + + +class CustomVariable(proto.Message): + r"""A custom variable. + + Attributes: + conversion_custom_variable (str): + Resource name of the custom variable + associated with this conversion. Note: Although + this resource name consists of a customer id and + a conversion custom variable id, validation will + ignore the customer id and use the conversion + custom variable id as the sole identifier of the + conversion custom variable. + value (str): + The value string of this custom variable. + The value of the custom variable should not + contain private customer data, such as email + addresses or phone numbers. + """ + + conversion_custom_variable = proto.Field(proto.STRING, number=1,) + value = proto.Field(proto.STRING, number=2,) + + +class CartData(proto.Message): + r"""Contains additional information about cart data. + + Attributes: + merchant_id (int): + The Merchant Center ID where the items are + uploaded. + feed_country_code (str): + The country code associated with the feed + where the items are uploaded. + feed_language_code (str): + The language code associated with the feed + where the items are uploaded. + local_transaction_cost (float): + Sum of all transaction level discounts, such + as free shipping and coupon discounts for the + whole cart. The currency code is the same as + that in the ClickConversion message. + items (Sequence[google.ads.googleads.v12.services.types.CartData.Item]): + Data of the items purchased. + """ + + class Item(proto.Message): + r"""Contains data of the items purchased. + + Attributes: + product_id (str): + The shopping id of the item. Must be equal to + the Merchant Center product identifier. + quantity (int): + Number of items sold. + unit_price (float): + Unit price excluding tax, shipping, and any + transaction level discounts. The currency code + is the same as that in the ClickConversion + message. + """ + + product_id = proto.Field(proto.STRING, number=1,) + quantity = proto.Field(proto.INT32, number=2,) + unit_price = proto.Field(proto.DOUBLE, number=3,) + + merchant_id = proto.Field(proto.INT64, number=6,) + feed_country_code = proto.Field(proto.STRING, number=2,) + feed_language_code = proto.Field(proto.STRING, number=3,) + local_transaction_cost = proto.Field(proto.DOUBLE, number=4,) + items = proto.RepeatedField(proto.MESSAGE, number=5, message=Item,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_value_rule_service.py b/google/ads/googleads/v12/services/types/conversion_value_rule_service.py new file mode 100644 index 000000000..c76527975 --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_value_rule_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + conversion_value_rule as gagr_conversion_value_rule, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateConversionValueRulesRequest", + "ConversionValueRuleOperation", + "MutateConversionValueRulesResponse", + "MutateConversionValueRuleResult", + }, +) + + +class MutateConversionValueRulesRequest(proto.Message): + r"""Request message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v12.services.ConversionValueRuleService.MutateConversionValueRules]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + conversion value rules are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionValueRuleOperation]): + Required. The list of operations to perform + on individual conversion value rules. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionValueRuleOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=5,) + validate_only = proto.Field(proto.BOOL, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ConversionValueRuleOperation(proto.Message): + r"""A single operation (create, update, remove) on a conversion + value rule. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ConversionValueRule): + Create operation: No resource name is + expected for the new conversion value rule. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ConversionValueRule): + Update operation: The conversion value rule + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed conversion + value rule is expected, in this format: + + ``customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_conversion_value_rule.ConversionValueRule, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_conversion_value_rule.ConversionValueRule, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateConversionValueRulesResponse(proto.Message): + r"""Response message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v12.services.ConversionValueRuleService.MutateConversionValueRules]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateConversionValueRuleResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateConversionValueRuleResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + + +class MutateConversionValueRuleResult(proto.Message): + r"""The result for the conversion value rule mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + conversion_value_rule (google.ads.googleads.v12.resources.types.ConversionValueRule): + The mutated conversion value rule with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + conversion_value_rule = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_conversion_value_rule.ConversionValueRule, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/conversion_value_rule_set_service.py b/google/ads/googleads/v12/services/types/conversion_value_rule_set_service.py new file mode 100644 index 000000000..053f8164e --- /dev/null +++ b/google/ads/googleads/v12/services/types/conversion_value_rule_set_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + conversion_value_rule_set as gagr_conversion_value_rule_set, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateConversionValueRuleSetsRequest", + "ConversionValueRuleSetOperation", + "MutateConversionValueRuleSetsResponse", + "MutateConversionValueRuleSetResult", + }, +) + + +class MutateConversionValueRuleSetsRequest(proto.Message): + r"""Request message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v12.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + conversion value rule sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ConversionValueRuleSetOperation]): + Required. The list of operations to perform + on individual conversion value rule sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ConversionValueRuleSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=5,) + validate_only = proto.Field(proto.BOOL, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ConversionValueRuleSetOperation(proto.Message): + r"""A single operation (create, update, remove) on a conversion + value rule set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ConversionValueRuleSet): + Create operation: No resource name is + expected for the new conversion value rule set. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ConversionValueRuleSet): + Update operation: The conversion value rule + set is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed conversion + value rule set is expected, in this format: + + ``customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_conversion_value_rule_set.ConversionValueRuleSet, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_conversion_value_rule_set.ConversionValueRuleSet, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateConversionValueRuleSetsResponse(proto.Message): + r"""Response message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v12.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateConversionValueRuleSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateConversionValueRuleSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateConversionValueRuleSetResult(proto.Message): + r"""The result for the conversion value rule set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + conversion_value_rule_set (google.ads.googleads.v12.resources.types.ConversionValueRuleSet): + The mutated conversion value rule set with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + conversion_value_rule_set = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_conversion_value_rule_set.ConversionValueRuleSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/custom_audience_service.py b/google/ads/googleads/v12/services/types/custom_audience_service.py new file mode 100644 index 000000000..3bb535226 --- /dev/null +++ b/google/ads/googleads/v12/services/types/custom_audience_service.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import custom_audience +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomAudiencesRequest", + "CustomAudienceOperation", + "MutateCustomAudiencesResponse", + "MutateCustomAudienceResult", + }, +) + + +class MutateCustomAudiencesRequest(proto.Message): + r"""Request message for + [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v12.services.CustomAudienceService.MutateCustomAudiences]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose custom + audiences are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomAudienceOperation]): + Required. The list of operations to perform + on individual custom audiences. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomAudienceOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class CustomAudienceOperation(proto.Message): + r"""A single operation (create, update) on a custom audience. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomAudience): + Create operation: No resource name is + expected for the new custom audience. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomAudience): + Update operation: The custom audience is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed custom + audience is expected, in this format: + + ``customers/{customer_id}/customAudiences/{custom_audience_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=custom_audience.CustomAudience, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=custom_audience.CustomAudience, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCustomAudiencesResponse(proto.Message): + r"""Response message for custom audience mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomAudienceResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomAudienceResult", + ) + + +class MutateCustomAudienceResult(proto.Message): + r"""The result for the custom audience mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/custom_conversion_goal_service.py b/google/ads/googleads/v12/services/types/custom_conversion_goal_service.py new file mode 100644 index 000000000..5088cc363 --- /dev/null +++ b/google/ads/googleads/v12/services/types/custom_conversion_goal_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + custom_conversion_goal as gagr_custom_conversion_goal, +) +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomConversionGoalsRequest", + "CustomConversionGoalOperation", + "MutateCustomConversionGoalsResponse", + "MutateCustomConversionGoalResult", + }, +) + + +class MutateCustomConversionGoalsRequest(proto.Message): + r"""Request message for + [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v12.services.CustomConversionGoalService.MutateCustomConversionGoals]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose custom + conversion goals are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomConversionGoalOperation]): + Required. The list of operations to perform + on individual custom conversion goal. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomConversionGoalOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + response_content_type = proto.Field( + proto.ENUM, + number=4, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomConversionGoalOperation(proto.Message): + r"""A single operation (create, remove) on a custom conversion + goal. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomConversionGoal): + Create operation: No resource name is + expected for the new custom conversion goal + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomConversionGoal): + Update operation: The custom conversion goal + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed custom + conversion goal is expected, in this format: + + 'customers/{customer_id}/conversionActions/{ConversionGoal.custom_goal_config.conversion_type_ids}' + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_custom_conversion_goal.CustomConversionGoal, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_custom_conversion_goal.CustomConversionGoal, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCustomConversionGoalsResponse(proto.Message): + r"""Response message for a custom conversion goal mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomConversionGoalResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomConversionGoalResult", + ) + + +class MutateCustomConversionGoalResult(proto.Message): + r"""The result for the custom conversion goal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + custom_conversion_goal (google.ads.googleads.v12.resources.types.CustomConversionGoal): + The mutated CustomConversionGoal with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + custom_conversion_goal = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_custom_conversion_goal.CustomConversionGoal, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/custom_interest_service.py b/google/ads/googleads/v12/services/types/custom_interest_service.py new file mode 100644 index 000000000..48097af43 --- /dev/null +++ b/google/ads/googleads/v12/services/types/custom_interest_service.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import custom_interest +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomInterestsRequest", + "CustomInterestOperation", + "MutateCustomInterestsResponse", + "MutateCustomInterestResult", + }, +) + + +class MutateCustomInterestsRequest(proto.Message): + r"""Request message for + [CustomInterestService.MutateCustomInterests][google.ads.googleads.v12.services.CustomInterestService.MutateCustomInterests]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose custom + interests are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomInterestOperation]): + Required. The list of operations to perform + on individual custom interests. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomInterestOperation", + ) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class CustomInterestOperation(proto.Message): + r"""A single operation (create, update) on a custom interest. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomInterest): + Create operation: No resource name is + expected for the new custom interest. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomInterest): + Update operation: The custom interest is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=custom_interest.CustomInterest, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=custom_interest.CustomInterest, + ) + + +class MutateCustomInterestsResponse(proto.Message): + r"""Response message for custom interest mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomInterestResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomInterestResult", + ) + + +class MutateCustomInterestResult(proto.Message): + r"""The result for the custom interest mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_asset_service.py b/google/ads/googleads/v12/services/types/customer_asset_service.py new file mode 100644 index 000000000..f0de3a951 --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_asset_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_asset as gagr_customer_asset, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerAssetsRequest", + "CustomerAssetOperation", + "MutateCustomerAssetsResponse", + "MutateCustomerAssetResult", + }, +) + + +class MutateCustomerAssetsRequest(proto.Message): + r"""Request message for + [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v12.services.CustomerAssetService.MutateCustomerAssets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer assets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerAssetOperation]): + Required. The list of operations to perform + on individual customer assets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerAssetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerAssetOperation(proto.Message): + r"""A single operation (create, update, remove) on a customer + asset. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomerAsset): + Create operation: No resource name is + expected for the new customer asset. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomerAsset): + Update operation: The customer asset is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customer + asset is expected, in this format: + + ``customers/{customer_id}/customerAssets/{asset_id}~{field_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_asset.CustomerAsset, + ) + update = proto.Field( + proto.MESSAGE, + number=3, + oneof="operation", + message=gagr_customer_asset.CustomerAsset, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerAssetsResponse(proto.Message): + r"""Response message for a customer asset mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerAssetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomerAssetResult", + ) + + +class MutateCustomerAssetResult(proto.Message): + r"""The result for the customer asset mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_asset (google.ads.googleads.v12.resources.types.CustomerAsset): + The mutated customer asset with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_asset = proto.Field( + proto.MESSAGE, number=2, message=gagr_customer_asset.CustomerAsset, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_asset_set_service.py b/google/ads/googleads/v12/services/types/customer_asset_set_service.py new file mode 100644 index 000000000..20d73cd91 --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_asset_set_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_asset_set as gagr_customer_asset_set, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerAssetSetsRequest", + "CustomerAssetSetOperation", + "MutateCustomerAssetSetsResponse", + "MutateCustomerAssetSetResult", + }, +) + + +class MutateCustomerAssetSetsRequest(proto.Message): + r"""Request message for + [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v12.services.CustomerAssetSetService.MutateCustomerAssetSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer asset sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerAssetSetOperation]): + Required. The list of operations to perform + on individual customer asset sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerAssetSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerAssetSetOperation(proto.Message): + r"""A single operation (create, remove) on a customer asset set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.CustomerAssetSet): + Create operation: No resource name is + expected for the new customer asset set. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customer + asset set is expected, in this format: + ``customers/{customer_id}/customerAssetSets/{asset_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_asset_set.CustomerAssetSet, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerAssetSetsResponse(proto.Message): + r"""Response message for a customer asset set mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerAssetSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (e.g. auth errors), we return an RPC + level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomerAssetSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateCustomerAssetSetResult(proto.Message): + r"""The result for the customer asset set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_asset_set (google.ads.googleads.v12.resources.types.CustomerAssetSet): + The mutated customer asset set with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_asset_set = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_customer_asset_set.CustomerAssetSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_client_link_service.py b/google/ads/googleads/v12/services/types/customer_client_link_service.py new file mode 100644 index 000000000..f753ca6be --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_client_link_service.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import customer_client_link +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerClientLinkRequest", + "CustomerClientLinkOperation", + "MutateCustomerClientLinkResponse", + "MutateCustomerClientLinkResult", + }, +) + + +class MutateCustomerClientLinkRequest(proto.Message): + r"""Request message for + [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v12.services.CustomerClientLinkService.MutateCustomerClientLink]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer link are being modified. + operation (google.ads.googleads.v12.services.types.CustomerClientLinkOperation): + Required. The operation to perform on the + individual CustomerClientLink. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="CustomerClientLinkOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class CustomerClientLinkOperation(proto.Message): + r"""A single operation (create, update) on a CustomerClientLink. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomerClientLink): + Create operation: No resource name is + expected for the new link. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomerClientLink): + Update operation: The link is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=customer_client_link.CustomerClientLink, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=customer_client_link.CustomerClientLink, + ) + + +class MutateCustomerClientLinkResponse(proto.Message): + r"""Response message for a CustomerClientLink mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateCustomerClientLinkResult): + A result that identifies the resource + affected by the mutate request. + """ + + result = proto.Field( + proto.MESSAGE, number=1, message="MutateCustomerClientLinkResult", + ) + + +class MutateCustomerClientLinkResult(proto.Message): + r"""The result for a single customer client link mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_conversion_goal_service.py b/google/ads/googleads/v12/services/types/customer_conversion_goal_service.py new file mode 100644 index 000000000..44e051b1f --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_conversion_goal_service.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import customer_conversion_goal +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerConversionGoalsRequest", + "CustomerConversionGoalOperation", + "MutateCustomerConversionGoalsResponse", + "MutateCustomerConversionGoalResult", + }, +) + + +class MutateCustomerConversionGoalsRequest(proto.Message): + r"""Request message for + [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v12.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer conversion goals are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerConversionGoalOperation]): + Required. The list of operations to perform + on individual customer conversion goal. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerConversionGoalOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class CustomerConversionGoalOperation(proto.Message): + r"""A single operation (update) on a customer conversion goal. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.CustomerConversionGoal): + Update operation: The customer conversion + goal is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=customer_conversion_goal.CustomerConversionGoal, + ) + + +class MutateCustomerConversionGoalsResponse(proto.Message): + r"""Response message for a customer conversion goal mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerConversionGoalResult]): + All results for the mutate. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomerConversionGoalResult", + ) + + +class MutateCustomerConversionGoalResult(proto.Message): + r"""The result for the customer conversion goal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_customizer_service.py b/google/ads/googleads/v12/services/types/customer_customizer_service.py new file mode 100644 index 000000000..45886184a --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_customizer_service.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_customizer as gagr_customer_customizer, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerCustomizersRequest", + "CustomerCustomizerOperation", + "MutateCustomerCustomizersResponse", + "MutateCustomerCustomizerResult", + }, +) + + +class MutateCustomerCustomizersRequest(proto.Message): + r"""Request message for + [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v12.services.CustomerCustomizerService.MutateCustomerCustomizers]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer customizers are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerCustomizerOperation]): + Required. The list of operations to perform + on individual customer customizers. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerCustomizerOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerCustomizerOperation(proto.Message): + r"""A single operation (create, remove) on an customizer + attribute. + + 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: + create (google.ads.googleads.v12.resources.types.CustomerCustomizer): + Create operation: No resource name is + expected for the new customer customizer + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customer + customizer is expected, in this format: + ``customers/{customer_id}/customerCustomizers/{customizer_attribute_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_customizer.CustomerCustomizer, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerCustomizersResponse(proto.Message): + r"""Response message for an customizer attribute mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerCustomizerResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomerCustomizerResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateCustomerCustomizerResult(proto.Message): + r"""The result for the customizer attribute mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_customizer (google.ads.googleads.v12.resources.types.CustomerCustomizer): + The mutated CustomerCustomizer with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_customizer = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_customer_customizer.CustomerCustomizer, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_extension_setting_service.py b/google/ads/googleads/v12/services/types/customer_extension_setting_service.py new file mode 100644 index 000000000..93aec5e0a --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_extension_setting_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_extension_setting as gagr_customer_extension_setting, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerExtensionSettingsRequest", + "CustomerExtensionSettingOperation", + "MutateCustomerExtensionSettingsResponse", + "MutateCustomerExtensionSettingResult", + }, +) + + +class MutateCustomerExtensionSettingsRequest(proto.Message): + r"""Request message for + [CustomerExtensionSettingService.MutateCustomerExtensionSettings][google.ads.googleads.v12.services.CustomerExtensionSettingService.MutateCustomerExtensionSettings]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer extension settings are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerExtensionSettingOperation]): + Required. The list of operations to perform + on individual customer extension settings. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerExtensionSettingOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerExtensionSettingOperation(proto.Message): + r"""A single operation (create, update, remove) on a customer + extension setting. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomerExtensionSetting): + Create operation: No resource name is + expected for the new customer extension setting. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomerExtensionSetting): + Update operation: The customer extension + setting is expected to have a valid resource + name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customer + extension setting is expected, in this format: + + ``customers/{customer_id}/customerExtensionSettings/{extension_type}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_extension_setting.CustomerExtensionSetting, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_customer_extension_setting.CustomerExtensionSetting, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCustomerExtensionSettingsResponse(proto.Message): + r"""Response message for a customer extension setting mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerExtensionSettingResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomerExtensionSettingResult", + ) + + +class MutateCustomerExtensionSettingResult(proto.Message): + r"""The result for the customer extension setting mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_extension_setting (google.ads.googleads.v12.resources.types.CustomerExtensionSetting): + The mutated CustomerExtensionSetting with only mutable + fields after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_extension_setting = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_customer_extension_setting.CustomerExtensionSetting, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_feed_service.py b/google/ads/googleads/v12/services/types/customer_feed_service.py new file mode 100644 index 000000000..eb76c425d --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_feed_service.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_feed as gagr_customer_feed, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerFeedsRequest", + "CustomerFeedOperation", + "MutateCustomerFeedsResponse", + "MutateCustomerFeedResult", + }, +) + + +class MutateCustomerFeedsRequest(proto.Message): + r"""Request message for + [CustomerFeedService.MutateCustomerFeeds][google.ads.googleads.v12.services.CustomerFeedService.MutateCustomerFeeds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer feeds are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerFeedOperation]): + Required. The list of operations to perform + on individual customer feeds. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerFeedOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerFeedOperation(proto.Message): + r"""A single operation (create, update, remove) on a customer + feed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomerFeed): + Create operation: No resource name is + expected for the new customer feed. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.CustomerFeed): + Update operation: The customer feed is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customer + feed is expected, in this format: + + ``customers/{customer_id}/customerFeeds/{feed_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_feed.CustomerFeed, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_customer_feed.CustomerFeed, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateCustomerFeedsResponse(proto.Message): + r"""Response message for a customer feed mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerFeedResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomerFeedResult", + ) + + +class MutateCustomerFeedResult(proto.Message): + r"""The result for the customer feed mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_feed (google.ads.googleads.v12.resources.types.CustomerFeed): + The mutated customer feed with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_feed = proto.Field( + proto.MESSAGE, number=2, message=gagr_customer_feed.CustomerFeed, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_label_service.py b/google/ads/googleads/v12/services/types/customer_label_service.py new file mode 100644 index 000000000..1323de721 --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_label_service.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import customer_label +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerLabelsRequest", + "CustomerLabelOperation", + "MutateCustomerLabelsResponse", + "MutateCustomerLabelResult", + }, +) + + +class MutateCustomerLabelsRequest(proto.Message): + r"""Request message for + [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v12.services.CustomerLabelService.MutateCustomerLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose + customer-label relationships are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerLabelOperation]): + Required. The list of operations to perform + on customer-label relationships. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerLabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class CustomerLabelOperation(proto.Message): + r"""A single operation (create, remove) on a customer-label + relationship. + + 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: + create (google.ads.googleads.v12.resources.types.CustomerLabel): + Create operation: No resource name is + expected for the new customer-label + relationship. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the customer-label + relationship being removed, in this format: + + ``customers/{customer_id}/customerLabels/{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=customer_label.CustomerLabel, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerLabelsResponse(proto.Message): + r"""Response message for a customer labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomerLabelResult", + ) + + +class MutateCustomerLabelResult(proto.Message): + r"""The result for a customer label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_manager_link_service.py b/google/ads/googleads/v12/services/types/customer_manager_link_service.py new file mode 100644 index 000000000..b08fb799a --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_manager_link_service.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import customer_manager_link +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerManagerLinkRequest", + "MoveManagerLinkRequest", + "CustomerManagerLinkOperation", + "MutateCustomerManagerLinkResponse", + "MoveManagerLinkResponse", + "MutateCustomerManagerLinkResult", + }, +) + + +class MutateCustomerManagerLinkRequest(proto.Message): + r"""Request message for + [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v12.services.CustomerManagerLinkService.MutateCustomerManagerLink]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customer manager links are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerManagerLinkOperation]): + Required. The list of operations to perform + on individual customer manager links. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerManagerLinkOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class MoveManagerLinkRequest(proto.Message): + r"""Request message for + [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v12.services.CustomerManagerLinkService.MoveManagerLink]. + + Attributes: + customer_id (str): + Required. The ID of the client customer that + is being moved. + previous_customer_manager_link (str): + Required. The resource name of the previous + CustomerManagerLink. The resource name has the form: + ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` + new_manager (str): + Required. The resource name of the new manager customer that + the client wants to move to. Customer resource names have + the format: "customers/{customer_id}". + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + previous_customer_manager_link = proto.Field(proto.STRING, number=2,) + new_manager = proto.Field(proto.STRING, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class CustomerManagerLinkOperation(proto.Message): + r"""Updates the status of a CustomerManagerLink. + The following actions are possible: + 1. Update operation with status ACTIVE accepts a pending + invitation. 2. Update operation with status REFUSED declines a + pending invitation. 3. Update operation with status INACTIVE + terminates link to manager. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.CustomerManagerLink): + Update operation: The link is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=customer_manager_link.CustomerManagerLink, + ) + + +class MutateCustomerManagerLinkResponse(proto.Message): + r"""Response message for a CustomerManagerLink mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerManagerLinkResult]): + A result that identifies the resource + affected by the mutate request. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomerManagerLinkResult", + ) + + +class MoveManagerLinkResponse(proto.Message): + r"""Response message for a CustomerManagerLink moveManagerLink. + + Attributes: + resource_name (str): + Returned for successful operations. + Represents a CustomerManagerLink resource of the + newly created link between client customer and + new manager customer. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class MutateCustomerManagerLinkResult(proto.Message): + r"""The result for the customer manager link mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_negative_criterion_service.py b/google/ads/googleads/v12/services/types/customer_negative_criterion_service.py new file mode 100644 index 000000000..8c8d3a179 --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_negative_criterion_service.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customer_negative_criterion as gagr_customer_negative_criterion, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerNegativeCriteriaRequest", + "CustomerNegativeCriterionOperation", + "MutateCustomerNegativeCriteriaResponse", + "MutateCustomerNegativeCriteriaResult", + }, +) + + +class MutateCustomerNegativeCriteriaRequest(proto.Message): + r"""Request message for + [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v12.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + criteria are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomerNegativeCriterionOperation]): + Required. The list of operations to perform + on individual criteria. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomerNegativeCriterionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomerNegativeCriterionOperation(proto.Message): + r"""A single operation (create or remove) on a customer level + negative criterion. + + 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: + create (google.ads.googleads.v12.resources.types.CustomerNegativeCriterion): + Create operation: No resource name is + expected for the new criterion. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed criterion + is expected, in this format: + + ``customers/{customer_id}/customerNegativeCriteria/{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customer_negative_criterion.CustomerNegativeCriterion, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerNegativeCriteriaResponse(proto.Message): + r"""Response message for customer negative criterion mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomerNegativeCriteriaResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateCustomerNegativeCriteriaResult", + ) + + +class MutateCustomerNegativeCriteriaResult(proto.Message): + r"""The result for the criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer_negative_criterion (google.ads.googleads.v12.resources.types.CustomerNegativeCriterion): + The mutated criterion with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer_negative_criterion = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_customer_negative_criterion.CustomerNegativeCriterion, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_service.py b/google/ads/googleads/v12/services/types/customer_service.py new file mode 100644 index 000000000..c91da946e --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_service.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import access_role as gage_access_role +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import customer as gagr_customer +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerRequest", + "CreateCustomerClientRequest", + "CustomerOperation", + "CreateCustomerClientResponse", + "MutateCustomerResponse", + "MutateCustomerResult", + "ListAccessibleCustomersRequest", + "ListAccessibleCustomersResponse", + }, +) + + +class MutateCustomerRequest(proto.Message): + r"""Request message for + [CustomerService.MutateCustomer][google.ads.googleads.v12.services.CustomerService.MutateCustomer]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + modified. + operation (google.ads.googleads.v12.services.types.CustomerOperation): + Required. The operation to perform on the + customer + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=4, message="CustomerOperation", + ) + validate_only = proto.Field(proto.BOOL, number=5,) + response_content_type = proto.Field( + proto.ENUM, + number=6, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CreateCustomerClientRequest(proto.Message): + r"""Request message for + [CustomerService.CreateCustomerClient][google.ads.googleads.v12.services.CustomerService.CreateCustomerClient]. + + Attributes: + customer_id (str): + Required. The ID of the Manager under whom + client customer is being created. + customer_client (google.ads.googleads.v12.resources.types.Customer): + Required. The new client customer to create. + The resource name on this customer will be + ignored. + email_address (str): + Email address of the user who should be + invited on the created client customer. + Accessible only to customers on the allow-list. + + This field is a member of `oneof`_ ``_email_address``. + access_role (google.ads.googleads.v12.enums.types.AccessRoleEnum.AccessRole): + The proposed role of user on the created + client customer. Accessible only to customers on + the allow-list. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + customer_client = proto.Field( + proto.MESSAGE, number=2, message=gagr_customer.Customer, + ) + email_address = proto.Field(proto.STRING, number=5, optional=True,) + access_role = proto.Field( + proto.ENUM, number=4, enum=gage_access_role.AccessRoleEnum.AccessRole, + ) + validate_only = proto.Field(proto.BOOL, number=6,) + + +class CustomerOperation(proto.Message): + r"""A single update on a customer. + + Attributes: + update (google.ads.googleads.v12.resources.types.Customer): + Mutate operation. Only updates are supported + for customer. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + """ + + update = proto.Field( + proto.MESSAGE, number=1, message=gagr_customer.Customer, + ) + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + + +class CreateCustomerClientResponse(proto.Message): + r"""Response message for CreateCustomerClient mutate. + + Attributes: + resource_name (str): + The resource name of the newly created customer. Customer + resource names have the form: ``customers/{customer_id}``. + invitation_link (str): + Link for inviting user to access the created + customer. Accessible to allowlisted customers + only. + """ + + resource_name = proto.Field(proto.STRING, number=2,) + invitation_link = proto.Field(proto.STRING, number=3,) + + +class MutateCustomerResponse(proto.Message): + r"""Response message for customer mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateCustomerResult): + Result for the mutate. + """ + + result = proto.Field( + proto.MESSAGE, number=2, message="MutateCustomerResult", + ) + + +class MutateCustomerResult(proto.Message): + r"""The result for the customer mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customer (google.ads.googleads.v12.resources.types.Customer): + The mutated customer with only mutable fields after mutate. + The fields will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customer = proto.Field( + proto.MESSAGE, number=2, message=gagr_customer.Customer, + ) + + +class ListAccessibleCustomersRequest(proto.Message): + r"""Request message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v12.services.CustomerService.ListAccessibleCustomers]. + + """ + + +class ListAccessibleCustomersResponse(proto.Message): + r"""Response message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v12.services.CustomerService.ListAccessibleCustomers]. + + Attributes: + resource_names (Sequence[str]): + Resource name of customers directly + accessible by the user authenticating the call. + """ + + resource_names = proto.RepeatedField(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_user_access_invitation_service.py b/google/ads/googleads/v12/services/types/customer_user_access_invitation_service.py new file mode 100644 index 000000000..0fe538d81 --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_user_access_invitation_service.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + customer_user_access_invitation, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerUserAccessInvitationRequest", + "CustomerUserAccessInvitationOperation", + "MutateCustomerUserAccessInvitationResponse", + "MutateCustomerUserAccessInvitationResult", + }, +) + + +class MutateCustomerUserAccessInvitationRequest(proto.Message): + r"""Request message for + [CustomerUserAccessInvitation.MutateCustomerUserAccessInvitation][] + + Attributes: + customer_id (str): + Required. The ID of the customer whose access + invitation is being modified. + operation (google.ads.googleads.v12.services.types.CustomerUserAccessInvitationOperation): + Required. The operation to perform on the + access invitation + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, + number=2, + message="CustomerUserAccessInvitationOperation", + ) + + +class CustomerUserAccessInvitationOperation(proto.Message): + r"""A single operation (create or remove) on customer user access + invitation. + + 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: + create (google.ads.googleads.v12.resources.types.CustomerUserAccessInvitation): + Create operation: No resource name is + expected for the new access invitation. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the revoke invitation + is expected, in this format: + + ``customers/{customer_id}/customerUserAccessInvitations/{invitation_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=customer_user_access_invitation.CustomerUserAccessInvitation, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerUserAccessInvitationResponse(proto.Message): + r"""Response message for access invitation mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateCustomerUserAccessInvitationResult): + Result for the mutate. + """ + + result = proto.Field( + proto.MESSAGE, + number=1, + message="MutateCustomerUserAccessInvitationResult", + ) + + +class MutateCustomerUserAccessInvitationResult(proto.Message): + r"""The result for the access invitation mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customer_user_access_service.py b/google/ads/googleads/v12/services/types/customer_user_access_service.py new file mode 100644 index 000000000..b05a3becd --- /dev/null +++ b/google/ads/googleads/v12/services/types/customer_user_access_service.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import customer_user_access +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomerUserAccessRequest", + "CustomerUserAccessOperation", + "MutateCustomerUserAccessResponse", + "MutateCustomerUserAccessResult", + }, +) + + +class MutateCustomerUserAccessRequest(proto.Message): + r"""Mutate Request for + [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v12.services.CustomerUserAccessService.MutateCustomerUserAccess]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + modified. + operation (google.ads.googleads.v12.services.types.CustomerUserAccessOperation): + Required. The operation to perform on the + customer + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="CustomerUserAccessOperation", + ) + + +class CustomerUserAccessOperation(proto.Message): + r"""A single operation (update, remove) on customer user access. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.CustomerUserAccess): + Update operation: The customer user access is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed access is + expected, in this format: + + ``customers/{customer_id}/customerUserAccesses/{CustomerUserAccess.user_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=customer_user_access.CustomerUserAccess, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomerUserAccessResponse(proto.Message): + r"""Response message for customer user access mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateCustomerUserAccessResult): + Result for the mutate. + """ + + result = proto.Field( + proto.MESSAGE, number=1, message="MutateCustomerUserAccessResult", + ) + + +class MutateCustomerUserAccessResult(proto.Message): + r"""The result for the customer user access mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/customizer_attribute_service.py b/google/ads/googleads/v12/services/types/customizer_attribute_service.py new file mode 100644 index 000000000..35c0dda3c --- /dev/null +++ b/google/ads/googleads/v12/services/types/customizer_attribute_service.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + customizer_attribute as gagr_customizer_attribute, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateCustomizerAttributesRequest", + "CustomizerAttributeOperation", + "MutateCustomizerAttributesResponse", + "MutateCustomizerAttributeResult", + }, +) + + +class MutateCustomizerAttributesRequest(proto.Message): + r"""Request message for + [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v12.services.CustomizerAttributeService.MutateCustomizerAttributes]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + customizer attributes are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.CustomizerAttributeOperation]): + Required. The list of operations to perform + on individual customizer attributes. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="CustomizerAttributeOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class CustomizerAttributeOperation(proto.Message): + r"""A single operation (create, remove) on an customizer + attribute. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.CustomizerAttribute): + Create operation: No resource name is + expected for the new customizer attribute + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed customizer + attribute is expected, in this format: + ``customers/{customer_id}/customizerAttributes/{customizer_attribute_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_customizer_attribute.CustomizerAttribute, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateCustomizerAttributesResponse(proto.Message): + r"""Response message for an customizer attribute mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateCustomizerAttributeResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateCustomizerAttributeResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateCustomizerAttributeResult(proto.Message): + r"""The result for the customizer attribute mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + customizer_attribute (google.ads.googleads.v12.resources.types.CustomizerAttribute): + The mutated CustomizerAttribute with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + customizer_attribute = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_customizer_attribute.CustomizerAttribute, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/experiment_arm_service.py b/google/ads/googleads/v12/services/types/experiment_arm_service.py new file mode 100644 index 000000000..546c5d69d --- /dev/null +++ b/google/ads/googleads/v12/services/types/experiment_arm_service.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + experiment_arm as gagr_experiment_arm, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateExperimentArmsRequest", + "ExperimentArmOperation", + "MutateExperimentArmsResponse", + "MutateExperimentArmResult", + }, +) + + +class MutateExperimentArmsRequest(proto.Message): + r"""Request message for + [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v12.services.ExperimentArmService.MutateExperimentArms]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + experiments are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ExperimentArmOperation]): + Required. The list of operations to perform + on individual experiment arm. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ExperimentArmOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ExperimentArmOperation(proto.Message): + r"""A single operation on an experiment arm. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ExperimentArm): + Create operation + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ExperimentArm): + Update operation: The experiment arm is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: The experiment arm is expected to have a + valid resource name, in this format: + + ``customers/{customer_id}/experiments/{campaign_experiment_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_experiment_arm.ExperimentArm, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_experiment_arm.ExperimentArm, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateExperimentArmsResponse(proto.Message): + r"""Response message for experiment arm mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateExperimentArmResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateExperimentArmResult", + ) + + +class MutateExperimentArmResult(proto.Message): + r"""The result for the experiment arm mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + experiment_arm (google.ads.googleads.v12.resources.types.ExperimentArm): + The mutated experiment arm with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + experiment_arm = proto.Field( + proto.MESSAGE, number=2, message=gagr_experiment_arm.ExperimentArm, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/experiment_service.py b/google/ads/googleads/v12/services/types/experiment_service.py new file mode 100644 index 000000000..45ba733d2 --- /dev/null +++ b/google/ads/googleads/v12/services/types/experiment_service.py @@ -0,0 +1,324 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + experiment as gagr_experiment, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateExperimentsRequest", + "ExperimentOperation", + "MutateExperimentsResponse", + "MutateExperimentResult", + "EndExperimentRequest", + "ListExperimentAsyncErrorsRequest", + "ListExperimentAsyncErrorsResponse", + "GraduateExperimentRequest", + "CampaignBudgetMapping", + "ScheduleExperimentRequest", + "ScheduleExperimentMetadata", + "PromoteExperimentRequest", + "PromoteExperimentMetadata", + }, +) + + +class MutateExperimentsRequest(proto.Message): + r"""Request message for + [ExperimentService.MutateExperiments][google.ads.googleads.v12.services.ExperimentService.MutateExperiments]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + experiments are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ExperimentOperation]): + Required. The list of operations to perform + on individual experiments. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ExperimentOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class ExperimentOperation(proto.Message): + r"""A single operation on an experiment. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Experiment): + Create operation + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Experiment): + Update operation: The experiment is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: The experiment is expected to have a valid + resource name, in this format: + + ``customers/{customer_id}/experiments/{campaign_experiment_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_experiment.Experiment, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_experiment.Experiment, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateExperimentsResponse(proto.Message): + r"""Response message for experiment mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateExperimentResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateExperimentResult", + ) + + +class MutateExperimentResult(proto.Message): + r"""The result for the campaign experiment mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class EndExperimentRequest(proto.Message): + r"""Request message for + [ExperimentService.EndExperiment][google.ads.googleads.v12.services.ExperimentService.EndExperiment]. + + Attributes: + experiment (str): + Required. The resource name of the campaign + experiment to end. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + experiment = proto.Field(proto.STRING, number=1,) + validate_only = proto.Field(proto.BOOL, number=2,) + + +class ListExperimentAsyncErrorsRequest(proto.Message): + r"""Request message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v12.services.ExperimentService.ListExperimentAsyncErrors]. + + Attributes: + resource_name (str): + Required. The name of the experiment from + which to retrieve the async errors. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. Use the value obtained + from ``next_page_token`` in the previous response in order + to request the next page of results. + page_size (int): + Number of elements to retrieve in a single + page. When a page request is too large, the + server may decide to further limit the number of + returned resources. The maximum page size is + 1000. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + page_token = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + + +class ListExperimentAsyncErrorsResponse(proto.Message): + r"""Response message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v12.services.ExperimentService.ListExperimentAsyncErrors]. + + Attributes: + errors (Sequence[google.rpc.status_pb2.Status]): + details of the errors when performing the + asynchronous operation. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + """ + + @property + def raw_page(self): + return self + + errors = proto.RepeatedField( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class GraduateExperimentRequest(proto.Message): + r"""Request message for + [ExperimentService.GraduateExperiment][google.ads.googleads.v12.services.ExperimentService.GraduateExperiment]. + + Attributes: + experiment (str): + Required. The experiment to be graduated. + campaign_budget_mappings (Sequence[google.ads.googleads.v12.services.types.CampaignBudgetMapping]): + Required. List of campaign budget mappings + for graduation. Each campaign that appears here + will graduate, and will be assigned a new budget + that is paired with it in the mapping. The + maximum size is one. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + experiment = proto.Field(proto.STRING, number=1,) + campaign_budget_mappings = proto.RepeatedField( + proto.MESSAGE, number=2, message="CampaignBudgetMapping", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class CampaignBudgetMapping(proto.Message): + r"""The mapping of experiment campaign and budget to be + graduated. + + Attributes: + experiment_campaign (str): + Required. The experiment campaign to + graduate. + campaign_budget (str): + Required. The budget that should be attached + to the graduating experiment campaign. + """ + + experiment_campaign = proto.Field(proto.STRING, number=1,) + campaign_budget = proto.Field(proto.STRING, number=2,) + + +class ScheduleExperimentRequest(proto.Message): + r"""Request message for + [ExperimentService.ScheduleExperiment][google.ads.googleads.v12.services.ExperimentService.ScheduleExperiment]. + + Attributes: + resource_name (str): + Required. The scheduled experiment. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + validate_only = proto.Field(proto.BOOL, number=2,) + + +class ScheduleExperimentMetadata(proto.Message): + r"""The metadata of the scheduled experiment. + + Attributes: + experiment (str): + Required. The scheduled experiment. + """ + + experiment = proto.Field(proto.STRING, number=1,) + + +class PromoteExperimentRequest(proto.Message): + r"""Request message for + [ExperimentService.PromoteExperiment][google.ads.googleads.v12.services.ExperimentService.PromoteExperiment]. + + Attributes: + resource_name (str): + Required. The resource name of the experiment + to promote. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + validate_only = proto.Field(proto.BOOL, number=2,) + + +class PromoteExperimentMetadata(proto.Message): + r"""The metadata of the promoted experiment. + + Attributes: + experiment (str): + Required. The promoted experiment. + """ + + experiment = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/extension_feed_item_service.py b/google/ads/googleads/v12/services/types/extension_feed_item_service.py new file mode 100644 index 000000000..13af5f4e0 --- /dev/null +++ b/google/ads/googleads/v12/services/types/extension_feed_item_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + extension_feed_item as gagr_extension_feed_item, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateExtensionFeedItemsRequest", + "ExtensionFeedItemOperation", + "MutateExtensionFeedItemsResponse", + "MutateExtensionFeedItemResult", + }, +) + + +class MutateExtensionFeedItemsRequest(proto.Message): + r"""Request message for + [ExtensionFeedItemService.MutateExtensionFeedItems][google.ads.googleads.v12.services.ExtensionFeedItemService.MutateExtensionFeedItems]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + extension feed items are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.ExtensionFeedItemOperation]): + Required. The list of operations to perform + on individual extension feed items. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ExtensionFeedItemOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class ExtensionFeedItemOperation(proto.Message): + r"""A single operation (create, update, remove) on an extension + feed item. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.ExtensionFeedItem): + Create operation: No resource name is + expected for the new extension feed item. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.ExtensionFeedItem): + Update operation: The extension feed item is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed extension + feed item is expected, in this format: + + ``customers/{customer_id}/extensionFeedItems/{feed_item_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_extension_feed_item.ExtensionFeedItem, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_extension_feed_item.ExtensionFeedItem, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateExtensionFeedItemsResponse(proto.Message): + r"""Response message for an extension feed item mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateExtensionFeedItemResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateExtensionFeedItemResult", + ) + + +class MutateExtensionFeedItemResult(proto.Message): + r"""The result for the extension feed item mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + extension_feed_item (google.ads.googleads.v12.resources.types.ExtensionFeedItem): + The mutated extension feed item with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + extension_feed_item = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_extension_feed_item.ExtensionFeedItem, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_item_service.py b/google/ads/googleads/v12/services/types/feed_item_service.py new file mode 100644 index 000000000..8cd6e5dcf --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_item_service.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import feed_item as gagr_feed_item +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedItemsRequest", + "FeedItemOperation", + "MutateFeedItemsResponse", + "MutateFeedItemResult", + }, +) + + +class MutateFeedItemsRequest(proto.Message): + r"""Request message for + [FeedItemService.MutateFeedItems][google.ads.googleads.v12.services.FeedItemService.MutateFeedItems]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feed + items are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemOperation]): + Required. The list of operations to perform + on individual feed items. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedItemOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class FeedItemOperation(proto.Message): + r"""A single operation (create, update, remove) on an feed item. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.FeedItem): + Create operation: No resource name is + expected for the new feed item. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.FeedItem): + Update operation: The feed item is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed item + is expected, in this format: + + ``customers/{customer_id}/feedItems/{feed_id}~{feed_item_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_feed_item.FeedItem, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_feed_item.FeedItem, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateFeedItemsResponse(proto.Message): + r"""Response message for an feed item mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedItemResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateFeedItemResult", + ) + + +class MutateFeedItemResult(proto.Message): + r"""The result for the feed item mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + feed_item (google.ads.googleads.v12.resources.types.FeedItem): + The mutated feed item with only mutable fields after mutate. + The field will only be returned when response_content_type + is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed_item = proto.Field( + proto.MESSAGE, number=2, message=gagr_feed_item.FeedItem, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_item_set_link_service.py b/google/ads/googleads/v12/services/types/feed_item_set_link_service.py new file mode 100644 index 000000000..4fb30494b --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_item_set_link_service.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import feed_item_set_link +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedItemSetLinksRequest", + "FeedItemSetLinkOperation", + "MutateFeedItemSetLinksResponse", + "MutateFeedItemSetLinkResult", + }, +) + + +class MutateFeedItemSetLinksRequest(proto.Message): + r"""Request message for + [FeedItemSetLinkService.MutateFeedItemSetLinks][google.ads.googleads.v12.services.FeedItemSetLinkService.MutateFeedItemSetLinks]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feed + item set links are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemSetLinkOperation]): + Required. The list of operations to perform + on individual feed item set links. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedItemSetLinkOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class FeedItemSetLinkOperation(proto.Message): + r"""A single operation (create, update, remove) on a feed item + set link. + + 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: + create (google.ads.googleads.v12.resources.types.FeedItemSetLink): + Create operation: No resource name is + expected for the new feed item set link. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed item + set link is expected, in this format: + + ``customers/{customer_id}/feedItemSetLinks/{feed_id}_{feed_item_set_id}_{feed_item_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=feed_item_set_link.FeedItemSetLink, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateFeedItemSetLinksResponse(proto.Message): + r"""Response message for a feed item set link mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedItemSetLinkResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateFeedItemSetLinkResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateFeedItemSetLinkResult(proto.Message): + r"""The result for the feed item set link mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_item_set_service.py b/google/ads/googleads/v12/services/types/feed_item_set_service.py new file mode 100644 index 000000000..3621857b0 --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_item_set_service.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import feed_item_set +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedItemSetsRequest", + "FeedItemSetOperation", + "MutateFeedItemSetsResponse", + "MutateFeedItemSetResult", + }, +) + + +class MutateFeedItemSetsRequest(proto.Message): + r"""Request message for + [FeedItemSetService.MutateFeedItemSets][google.ads.googleads.v12.services.FeedItemSetService.MutateFeedItemSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feed + item sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemSetOperation]): + Required. The list of operations to perform + on individual feed item sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedItemSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class FeedItemSetOperation(proto.Message): + r"""A single operation (create, remove) on an feed item set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.FeedItemSet): + Create operation: No resource name is + expected for the new feed item set + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.FeedItemSet): + Update operation: The feed item set is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed item + is expected, in this format: + ``customers/{customer_id}/feedItems/{feed_id}~{feed_item_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=feed_item_set.FeedItemSet, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=feed_item_set.FeedItemSet, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateFeedItemSetsResponse(proto.Message): + r"""Response message for an feed item set mutate. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedItemSetResult]): + All results for the mutate. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateFeedItemSetResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class MutateFeedItemSetResult(proto.Message): + r"""The result for the feed item set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_item_target_service.py b/google/ads/googleads/v12/services/types/feed_item_target_service.py new file mode 100644 index 000000000..4efe0982b --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_item_target_service.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + feed_item_target as gagr_feed_item_target, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedItemTargetsRequest", + "FeedItemTargetOperation", + "MutateFeedItemTargetsResponse", + "MutateFeedItemTargetResult", + }, +) + + +class MutateFeedItemTargetsRequest(proto.Message): + r"""Request message for + [FeedItemTargetService.MutateFeedItemTargets][google.ads.googleads.v12.services.FeedItemTargetService.MutateFeedItemTargets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feed + item targets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedItemTargetOperation]): + Required. The list of operations to perform + on individual feed item targets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedItemTargetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class FeedItemTargetOperation(proto.Message): + r"""A single operation (create, remove) on an feed item target. + + 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: + create (google.ads.googleads.v12.resources.types.FeedItemTarget): + Create operation: No resource name is + expected for the new feed item target. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed item + target is expected, in this format: + + ``customers/{customer_id}/feedItemTargets/{feed_id}~{feed_item_id}~{feed_item_target_type}~{feed_item_target_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_feed_item_target.FeedItemTarget, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateFeedItemTargetsResponse(proto.Message): + r"""Response message for an feed item target mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedItemTargetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateFeedItemTargetResult", + ) + + +class MutateFeedItemTargetResult(proto.Message): + r"""The result for the feed item target mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + feed_item_target (google.ads.googleads.v12.resources.types.FeedItemTarget): + The mutated feed item target with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed_item_target = proto.Field( + proto.MESSAGE, number=2, message=gagr_feed_item_target.FeedItemTarget, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_mapping_service.py b/google/ads/googleads/v12/services/types/feed_mapping_service.py new file mode 100644 index 000000000..8ebea821c --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_mapping_service.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + feed_mapping as gagr_feed_mapping, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedMappingsRequest", + "FeedMappingOperation", + "MutateFeedMappingsResponse", + "MutateFeedMappingResult", + }, +) + + +class MutateFeedMappingsRequest(proto.Message): + r"""Request message for + [FeedMappingService.MutateFeedMappings][google.ads.googleads.v12.services.FeedMappingService.MutateFeedMappings]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feed + mappings are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedMappingOperation]): + Required. The list of operations to perform + on individual feed mappings. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedMappingOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class FeedMappingOperation(proto.Message): + r"""A single operation (create, remove) on a feed mapping. + + 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: + create (google.ads.googleads.v12.resources.types.FeedMapping): + Create operation: No resource name is + expected for the new feed mapping. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed + mapping is expected, in this format: + + ``customers/{customer_id}/feedMappings/{feed_id}~{feed_mapping_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_feed_mapping.FeedMapping, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateFeedMappingsResponse(proto.Message): + r"""Response message for a feed mapping mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedMappingResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateFeedMappingResult", + ) + + +class MutateFeedMappingResult(proto.Message): + r"""The result for the feed mapping mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + feed_mapping (google.ads.googleads.v12.resources.types.FeedMapping): + The mutated feed mapping with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed_mapping = proto.Field( + proto.MESSAGE, number=2, message=gagr_feed_mapping.FeedMapping, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/feed_service.py b/google/ads/googleads/v12/services/types/feed_service.py new file mode 100644 index 000000000..8911ebd50 --- /dev/null +++ b/google/ads/googleads/v12/services/types/feed_service.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import feed as gagr_feed +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateFeedsRequest", + "FeedOperation", + "MutateFeedsResponse", + "MutateFeedResult", + }, +) + + +class MutateFeedsRequest(proto.Message): + r"""Request message for + [FeedService.MutateFeeds][google.ads.googleads.v12.services.FeedService.MutateFeeds]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose feeds + are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.FeedOperation]): + Required. The list of operations to perform + on individual feeds. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="FeedOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class FeedOperation(proto.Message): + r"""A single operation (create, update, remove) on an feed. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Feed): + Create operation: No resource name is + expected for the new feed. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Feed): + Update operation: The feed is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed feed is + expected, in this format: + + ``customers/{customer_id}/feeds/{feed_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=gagr_feed.Feed, + ) + update = proto.Field( + proto.MESSAGE, number=2, oneof="operation", message=gagr_feed.Feed, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateFeedsResponse(proto.Message): + r"""Response message for an feed mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateFeedResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateFeedResult", + ) + + +class MutateFeedResult(proto.Message): + r"""The result for the feed mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + feed (google.ads.googleads.v12.resources.types.Feed): + The mutated feed with only mutable fields after mutate. The + field will only be returned when response_content_type is + set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + feed = proto.Field(proto.MESSAGE, number=2, message=gagr_feed.Feed,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/geo_target_constant_service.py b/google/ads/googleads/v12/services/types/geo_target_constant_service.py new file mode 100644 index 000000000..523be4e0b --- /dev/null +++ b/google/ads/googleads/v12/services/types/geo_target_constant_service.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + geo_target_constant as gagr_geo_target_constant, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "SuggestGeoTargetConstantsRequest", + "SuggestGeoTargetConstantsResponse", + "GeoTargetConstantSuggestion", + }, +) + + +class SuggestGeoTargetConstantsRequest(proto.Message): + r"""Request message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v12.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + 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: + locale (str): + If possible, returned geo targets are + translated using this locale. If not, en is used + by default. This is also used as a hint for + returned geo targets. + + This field is a member of `oneof`_ ``_locale``. + country_code (str): + Returned geo targets are restricted to this + country code. + + This field is a member of `oneof`_ ``_country_code``. + location_names (google.ads.googleads.v12.services.types.SuggestGeoTargetConstantsRequest.LocationNames): + The location names to search by. At most 25 + names can be set. + + This field is a member of `oneof`_ ``query``. + geo_targets (google.ads.googleads.v12.services.types.SuggestGeoTargetConstantsRequest.GeoTargets): + The geo target constant resource names to + filter by. + + This field is a member of `oneof`_ ``query``. + """ + + class LocationNames(proto.Message): + r"""A list of location names. + + Attributes: + names (Sequence[str]): + A list of location names. + """ + + names = proto.RepeatedField(proto.STRING, number=2,) + + class GeoTargets(proto.Message): + r"""A list of geo target constant resource names. + + Attributes: + geo_target_constants (Sequence[str]): + A list of geo target constant resource names. + """ + + geo_target_constants = proto.RepeatedField(proto.STRING, number=2,) + + locale = proto.Field(proto.STRING, number=6, optional=True,) + country_code = proto.Field(proto.STRING, number=7, optional=True,) + location_names = proto.Field( + proto.MESSAGE, number=1, oneof="query", message=LocationNames, + ) + geo_targets = proto.Field( + proto.MESSAGE, number=2, oneof="query", message=GeoTargets, + ) + + +class SuggestGeoTargetConstantsResponse(proto.Message): + r"""Response message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v12.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + + Attributes: + geo_target_constant_suggestions (Sequence[google.ads.googleads.v12.services.types.GeoTargetConstantSuggestion]): + Geo target constant suggestions. + """ + + geo_target_constant_suggestions = proto.RepeatedField( + proto.MESSAGE, number=1, message="GeoTargetConstantSuggestion", + ) + + +class GeoTargetConstantSuggestion(proto.Message): + r"""A geo target constant suggestion. + + Attributes: + locale (str): + The language this GeoTargetConstantSuggestion + is currently translated to. It affects the name + of geo target fields. For example, if locale=en, + then name=Spain. If locale=es, then name=España. + The default locale will be returned if no + translation exists for the locale in the + request. + + This field is a member of `oneof`_ ``_locale``. + reach (int): + Approximate user population that will be + targeted, rounded to the nearest 100. + + This field is a member of `oneof`_ ``_reach``. + search_term (str): + If the request searched by location name, + this is the location name that matched the geo + target. + + This field is a member of `oneof`_ ``_search_term``. + geo_target_constant (google.ads.googleads.v12.resources.types.GeoTargetConstant): + The GeoTargetConstant result. + geo_target_constant_parents (Sequence[google.ads.googleads.v12.resources.types.GeoTargetConstant]): + The list of parents of the geo target + constant. + """ + + locale = proto.Field(proto.STRING, number=6, optional=True,) + reach = proto.Field(proto.INT64, number=7, optional=True,) + search_term = proto.Field(proto.STRING, number=8, optional=True,) + geo_target_constant = proto.Field( + proto.MESSAGE, + number=4, + message=gagr_geo_target_constant.GeoTargetConstant, + ) + geo_target_constant_parents = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=gagr_geo_target_constant.GeoTargetConstant, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/google_ads_field_service.py b/google/ads/googleads/v12/services/types/google_ads_field_service.py new file mode 100644 index 000000000..ea66aa2a8 --- /dev/null +++ b/google/ads/googleads/v12/services/types/google_ads_field_service.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import google_ads_field + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "GetGoogleAdsFieldRequest", + "SearchGoogleAdsFieldsRequest", + "SearchGoogleAdsFieldsResponse", + }, +) + + +class GetGoogleAdsFieldRequest(proto.Message): + r"""Request message for + [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v12.services.GoogleAdsFieldService.GetGoogleAdsField]. + + Attributes: + resource_name (str): + Required. The resource name of the field to + get. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class SearchGoogleAdsFieldsRequest(proto.Message): + r"""Request message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v12.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + + Attributes: + query (str): + Required. The query string. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. Use the value obtained + from ``next_page_token`` in the previous response in order + to request the next page of results. + page_size (int): + Number of elements to retrieve in a single + page. When too large a page is requested, the + server may decide to further limit the number of + returned resources. + """ + + query = proto.Field(proto.STRING, number=1,) + page_token = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + + +class SearchGoogleAdsFieldsResponse(proto.Message): + r"""Response message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v12.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + + Attributes: + results (Sequence[google.ads.googleads.v12.resources.types.GoogleAdsField]): + The list of fields that matched the query. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + total_results_count (int): + Total number of results that match the query + ignoring the LIMIT clause. + """ + + @property + def raw_page(self): + return self + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message=google_ads_field.GoogleAdsField, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + total_results_count = proto.Field(proto.INT64, number=3,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/google_ads_service.py b/google/ads/googleads/v12/services/types/google_ads_service.py new file mode 100644 index 000000000..4949546c4 --- /dev/null +++ b/google/ads/googleads/v12/services/types/google_ads_service.py @@ -0,0 +1,3420 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import metrics as gagc_metrics +from google.ads.googleads.v12.common.types import segments as gagc_segments +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.enums.types import ( + summary_row_setting as gage_summary_row_setting, +) +from google.ads.googleads.v12.resources.types import ( + accessible_bidding_strategy as gagr_accessible_bidding_strategy, +) +from google.ads.googleads.v12.resources.types import ( + account_budget as gagr_account_budget, +) +from google.ads.googleads.v12.resources.types import ( + account_budget_proposal as gagr_account_budget_proposal, +) +from google.ads.googleads.v12.resources.types import ( + account_link as gagr_account_link, +) +from google.ads.googleads.v12.resources.types import ad_group as gagr_ad_group +from google.ads.googleads.v12.resources.types import ( + ad_group_ad as gagr_ad_group_ad, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_ad_asset_combination_view as gagr_ad_group_ad_asset_combination_view, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_ad_asset_view as gagr_ad_group_ad_asset_view, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_ad_label as gagr_ad_group_ad_label, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_asset as gagr_ad_group_asset, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_asset_set as gagr_ad_group_asset_set, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_audience_view as gagr_ad_group_audience_view, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_bid_modifier as gagr_ad_group_bid_modifier, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion as gagr_ad_group_criterion, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion_customizer as gagr_ad_group_criterion_customizer, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion_label as gagr_ad_group_criterion_label, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_criterion_simulation as gagr_ad_group_criterion_simulation, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_customizer as gagr_ad_group_customizer, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_extension_setting as gagr_ad_group_extension_setting, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_feed as gagr_ad_group_feed, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_label as gagr_ad_group_label, +) +from google.ads.googleads.v12.resources.types import ( + ad_group_simulation as gagr_ad_group_simulation, +) +from google.ads.googleads.v12.resources.types import ( + ad_parameter as gagr_ad_parameter, +) +from google.ads.googleads.v12.resources.types import ( + ad_schedule_view as gagr_ad_schedule_view, +) +from google.ads.googleads.v12.resources.types import ( + age_range_view as gagr_age_range_view, +) +from google.ads.googleads.v12.resources.types import asset as gagr_asset +from google.ads.googleads.v12.resources.types import ( + asset_field_type_view as gagr_asset_field_type_view, +) +from google.ads.googleads.v12.resources.types import ( + asset_group as gagr_asset_group, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_asset as gagr_asset_group_asset, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_listing_group_filter as gagr_asset_group_listing_group_filter, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_product_group_view as gagr_asset_group_product_group_view, +) +from google.ads.googleads.v12.resources.types import ( + asset_group_signal as gagr_asset_group_signal, +) +from google.ads.googleads.v12.resources.types import asset_set as gagr_asset_set +from google.ads.googleads.v12.resources.types import ( + asset_set_asset as gagr_asset_set_asset, +) +from google.ads.googleads.v12.resources.types import ( + asset_set_type_view as gagr_asset_set_type_view, +) +from google.ads.googleads.v12.resources.types import audience as gagr_audience +from google.ads.googleads.v12.resources.types import batch_job as gagr_batch_job +from google.ads.googleads.v12.resources.types import ( + bidding_data_exclusion as gagr_bidding_data_exclusion, +) +from google.ads.googleads.v12.resources.types import ( + bidding_seasonality_adjustment as gagr_bidding_seasonality_adjustment, +) +from google.ads.googleads.v12.resources.types import ( + bidding_strategy as gagr_bidding_strategy, +) +from google.ads.googleads.v12.resources.types import ( + bidding_strategy_simulation as gagr_bidding_strategy_simulation, +) +from google.ads.googleads.v12.resources.types import ( + billing_setup as gagr_billing_setup, +) +from google.ads.googleads.v12.resources.types import call_view as gagr_call_view +from google.ads.googleads.v12.resources.types import campaign as gagr_campaign +from google.ads.googleads.v12.resources.types import ( + campaign_asset as gagr_campaign_asset, +) +from google.ads.googleads.v12.resources.types import ( + campaign_asset_set as gagr_campaign_asset_set, +) +from google.ads.googleads.v12.resources.types import ( + campaign_audience_view as gagr_campaign_audience_view, +) +from google.ads.googleads.v12.resources.types import ( + campaign_bid_modifier as gagr_campaign_bid_modifier, +) +from google.ads.googleads.v12.resources.types import ( + campaign_budget as gagr_campaign_budget, +) +from google.ads.googleads.v12.resources.types import ( + campaign_conversion_goal as gagr_campaign_conversion_goal, +) +from google.ads.googleads.v12.resources.types import ( + campaign_criterion as gagr_campaign_criterion, +) +from google.ads.googleads.v12.resources.types import ( + campaign_criterion_simulation as gagr_campaign_criterion_simulation, +) +from google.ads.googleads.v12.resources.types import ( + campaign_customizer as gagr_campaign_customizer, +) +from google.ads.googleads.v12.resources.types import ( + campaign_draft as gagr_campaign_draft, +) +from google.ads.googleads.v12.resources.types import ( + campaign_extension_setting as gagr_campaign_extension_setting, +) +from google.ads.googleads.v12.resources.types import ( + campaign_feed as gagr_campaign_feed, +) +from google.ads.googleads.v12.resources.types import ( + campaign_group as gagr_campaign_group, +) +from google.ads.googleads.v12.resources.types import ( + campaign_label as gagr_campaign_label, +) +from google.ads.googleads.v12.resources.types import ( + campaign_shared_set as gagr_campaign_shared_set, +) +from google.ads.googleads.v12.resources.types import ( + campaign_simulation as gagr_campaign_simulation, +) +from google.ads.googleads.v12.resources.types import ( + carrier_constant as gagr_carrier_constant, +) +from google.ads.googleads.v12.resources.types import ( + change_event as gagr_change_event, +) +from google.ads.googleads.v12.resources.types import ( + change_status as gagr_change_status, +) +from google.ads.googleads.v12.resources.types import ( + click_view as gagr_click_view, +) +from google.ads.googleads.v12.resources.types import ( + combined_audience as gagr_combined_audience, +) +from google.ads.googleads.v12.resources.types import ( + conversion_action as gagr_conversion_action, +) +from google.ads.googleads.v12.resources.types import ( + conversion_custom_variable as gagr_conversion_custom_variable, +) +from google.ads.googleads.v12.resources.types import ( + conversion_goal_campaign_config as gagr_conversion_goal_campaign_config, +) +from google.ads.googleads.v12.resources.types import ( + conversion_value_rule as gagr_conversion_value_rule, +) +from google.ads.googleads.v12.resources.types import ( + conversion_value_rule_set as gagr_conversion_value_rule_set, +) +from google.ads.googleads.v12.resources.types import ( + currency_constant as gagr_currency_constant, +) +from google.ads.googleads.v12.resources.types import ( + custom_audience as gagr_custom_audience, +) +from google.ads.googleads.v12.resources.types import ( + custom_conversion_goal as gagr_custom_conversion_goal, +) +from google.ads.googleads.v12.resources.types import ( + custom_interest as gagr_custom_interest, +) +from google.ads.googleads.v12.resources.types import customer as gagr_customer +from google.ads.googleads.v12.resources.types import ( + customer_asset as gagr_customer_asset, +) +from google.ads.googleads.v12.resources.types import ( + customer_asset_set as gagr_customer_asset_set, +) +from google.ads.googleads.v12.resources.types import ( + customer_client as gagr_customer_client, +) +from google.ads.googleads.v12.resources.types import ( + customer_client_link as gagr_customer_client_link, +) +from google.ads.googleads.v12.resources.types import ( + customer_conversion_goal as gagr_customer_conversion_goal, +) +from google.ads.googleads.v12.resources.types import ( + customer_customizer as gagr_customer_customizer, +) +from google.ads.googleads.v12.resources.types import ( + customer_extension_setting as gagr_customer_extension_setting, +) +from google.ads.googleads.v12.resources.types import ( + customer_feed as gagr_customer_feed, +) +from google.ads.googleads.v12.resources.types import ( + customer_label as gagr_customer_label, +) +from google.ads.googleads.v12.resources.types import ( + customer_manager_link as gagr_customer_manager_link, +) +from google.ads.googleads.v12.resources.types import ( + customer_negative_criterion as gagr_customer_negative_criterion, +) +from google.ads.googleads.v12.resources.types import ( + customer_user_access as gagr_customer_user_access, +) +from google.ads.googleads.v12.resources.types import ( + customer_user_access_invitation as gagr_customer_user_access_invitation, +) +from google.ads.googleads.v12.resources.types import ( + customizer_attribute as gagr_customizer_attribute, +) +from google.ads.googleads.v12.resources.types import ( + detail_placement_view as gagr_detail_placement_view, +) +from google.ads.googleads.v12.resources.types import ( + detailed_demographic as gagr_detailed_demographic, +) +from google.ads.googleads.v12.resources.types import ( + display_keyword_view as gagr_display_keyword_view, +) +from google.ads.googleads.v12.resources.types import ( + distance_view as gagr_distance_view, +) +from google.ads.googleads.v12.resources.types import ( + domain_category as gagr_domain_category, +) +from google.ads.googleads.v12.resources.types import ( + dynamic_search_ads_search_term_view as gagr_dynamic_search_ads_search_term_view, +) +from google.ads.googleads.v12.resources.types import ( + expanded_landing_page_view as gagr_expanded_landing_page_view, +) +from google.ads.googleads.v12.resources.types import ( + experiment as gagr_experiment, +) +from google.ads.googleads.v12.resources.types import ( + experiment_arm as gagr_experiment_arm, +) +from google.ads.googleads.v12.resources.types import ( + extension_feed_item as gagr_extension_feed_item, +) +from google.ads.googleads.v12.resources.types import feed as gagr_feed +from google.ads.googleads.v12.resources.types import feed_item as gagr_feed_item +from google.ads.googleads.v12.resources.types import ( + feed_item_set as gagr_feed_item_set, +) +from google.ads.googleads.v12.resources.types import ( + feed_item_set_link as gagr_feed_item_set_link, +) +from google.ads.googleads.v12.resources.types import ( + feed_item_target as gagr_feed_item_target, +) +from google.ads.googleads.v12.resources.types import ( + feed_mapping as gagr_feed_mapping, +) +from google.ads.googleads.v12.resources.types import ( + feed_placeholder_view as gagr_feed_placeholder_view, +) +from google.ads.googleads.v12.resources.types import ( + gender_view as gagr_gender_view, +) +from google.ads.googleads.v12.resources.types import ( + geo_target_constant as gagr_geo_target_constant, +) +from google.ads.googleads.v12.resources.types import ( + geographic_view as gagr_geographic_view, +) +from google.ads.googleads.v12.resources.types import ( + group_placement_view as gagr_group_placement_view, +) +from google.ads.googleads.v12.resources.types import ( + hotel_group_view as gagr_hotel_group_view, +) +from google.ads.googleads.v12.resources.types import ( + hotel_performance_view as gagr_hotel_performance_view, +) +from google.ads.googleads.v12.resources.types import ( + hotel_reconciliation as gagr_hotel_reconciliation, +) +from google.ads.googleads.v12.resources.types import ( + income_range_view as gagr_income_range_view, +) +from google.ads.googleads.v12.resources.types import ( + keyword_plan as gagr_keyword_plan, +) +from google.ads.googleads.v12.resources.types import ( + keyword_plan_ad_group as gagr_keyword_plan_ad_group, +) +from google.ads.googleads.v12.resources.types import ( + keyword_plan_ad_group_keyword as gagr_keyword_plan_ad_group_keyword, +) +from google.ads.googleads.v12.resources.types import ( + keyword_plan_campaign as gagr_keyword_plan_campaign, +) +from google.ads.googleads.v12.resources.types import ( + keyword_plan_campaign_keyword as gagr_keyword_plan_campaign_keyword, +) +from google.ads.googleads.v12.resources.types import ( + keyword_theme_constant as gagr_keyword_theme_constant, +) +from google.ads.googleads.v12.resources.types import ( + keyword_view as gagr_keyword_view, +) +from google.ads.googleads.v12.resources.types import label as gagr_label +from google.ads.googleads.v12.resources.types import ( + landing_page_view as gagr_landing_page_view, +) +from google.ads.googleads.v12.resources.types import ( + language_constant as gagr_language_constant, +) +from google.ads.googleads.v12.resources.types import ( + lead_form_submission_data as gagr_lead_form_submission_data, +) +from google.ads.googleads.v12.resources.types import ( + life_event as gagr_life_event, +) +from google.ads.googleads.v12.resources.types import ( + location_view as gagr_location_view, +) +from google.ads.googleads.v12.resources.types import ( + managed_placement_view as gagr_managed_placement_view, +) +from google.ads.googleads.v12.resources.types import ( + media_file as gagr_media_file, +) +from google.ads.googleads.v12.resources.types import ( + mobile_app_category_constant as gagr_mobile_app_category_constant, +) +from google.ads.googleads.v12.resources.types import ( + mobile_device_constant as gagr_mobile_device_constant, +) +from google.ads.googleads.v12.resources.types import ( + offline_user_data_job as gagr_offline_user_data_job, +) +from google.ads.googleads.v12.resources.types import ( + operating_system_version_constant as gagr_operating_system_version_constant, +) +from google.ads.googleads.v12.resources.types import ( + paid_organic_search_term_view as gagr_paid_organic_search_term_view, +) +from google.ads.googleads.v12.resources.types import ( + parental_status_view as gagr_parental_status_view, +) +from google.ads.googleads.v12.resources.types import ( + per_store_view as gagr_per_store_view, +) +from google.ads.googleads.v12.resources.types import ( + product_bidding_category_constant as gagr_product_bidding_category_constant, +) +from google.ads.googleads.v12.resources.types import ( + product_group_view as gagr_product_group_view, +) +from google.ads.googleads.v12.resources.types import ( + recommendation as gagr_recommendation, +) +from google.ads.googleads.v12.resources.types import ( + remarketing_action as gagr_remarketing_action, +) +from google.ads.googleads.v12.resources.types import ( + search_term_view as gagr_search_term_view, +) +from google.ads.googleads.v12.resources.types import ( + shared_criterion as gagr_shared_criterion, +) +from google.ads.googleads.v12.resources.types import ( + shared_set as gagr_shared_set, +) +from google.ads.googleads.v12.resources.types import ( + shopping_performance_view as gagr_shopping_performance_view, +) +from google.ads.googleads.v12.resources.types import ( + smart_campaign_search_term_view as gagr_smart_campaign_search_term_view, +) +from google.ads.googleads.v12.resources.types import ( + smart_campaign_setting as gagr_smart_campaign_setting, +) +from google.ads.googleads.v12.resources.types import ( + third_party_app_analytics_link as gagr_third_party_app_analytics_link, +) +from google.ads.googleads.v12.resources.types import ( + topic_constant as gagr_topic_constant, +) +from google.ads.googleads.v12.resources.types import ( + topic_view as gagr_topic_view, +) +from google.ads.googleads.v12.resources.types import ( + user_interest as gagr_user_interest, +) +from google.ads.googleads.v12.resources.types import user_list as gagr_user_list +from google.ads.googleads.v12.resources.types import ( + user_location_view as gagr_user_location_view, +) +from google.ads.googleads.v12.resources.types import video as gagr_video +from google.ads.googleads.v12.resources.types import ( + webpage_view as gagr_webpage_view, +) +from google.ads.googleads.v12.services.types import ad_group_ad_label_service +from google.ads.googleads.v12.services.types import ad_group_ad_service +from google.ads.googleads.v12.services.types import ad_group_asset_service +from google.ads.googleads.v12.services.types import ( + ad_group_bid_modifier_service, +) +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_customizer_service, +) +from google.ads.googleads.v12.services.types import ( + ad_group_criterion_label_service, +) +from google.ads.googleads.v12.services.types import ad_group_criterion_service +from google.ads.googleads.v12.services.types import ad_group_customizer_service +from google.ads.googleads.v12.services.types import ( + ad_group_extension_setting_service, +) +from google.ads.googleads.v12.services.types import ad_group_feed_service +from google.ads.googleads.v12.services.types import ad_group_label_service +from google.ads.googleads.v12.services.types import ad_group_service +from google.ads.googleads.v12.services.types import ad_parameter_service +from google.ads.googleads.v12.services.types import ad_service +from google.ads.googleads.v12.services.types import asset_group_asset_service +from google.ads.googleads.v12.services.types import ( + asset_group_listing_group_filter_service, +) +from google.ads.googleads.v12.services.types import asset_group_service +from google.ads.googleads.v12.services.types import asset_group_signal_service +from google.ads.googleads.v12.services.types import asset_service +from google.ads.googleads.v12.services.types import asset_set_asset_service +from google.ads.googleads.v12.services.types import asset_set_service +from google.ads.googleads.v12.services.types import audience_service +from google.ads.googleads.v12.services.types import ( + bidding_data_exclusion_service, +) +from google.ads.googleads.v12.services.types import ( + bidding_seasonality_adjustment_service, +) +from google.ads.googleads.v12.services.types import bidding_strategy_service +from google.ads.googleads.v12.services.types import campaign_asset_service +from google.ads.googleads.v12.services.types import campaign_asset_set_service +from google.ads.googleads.v12.services.types import ( + campaign_bid_modifier_service, +) +from google.ads.googleads.v12.services.types import campaign_budget_service +from google.ads.googleads.v12.services.types import ( + campaign_conversion_goal_service, +) +from google.ads.googleads.v12.services.types import campaign_criterion_service +from google.ads.googleads.v12.services.types import campaign_customizer_service +from google.ads.googleads.v12.services.types import campaign_draft_service +from google.ads.googleads.v12.services.types import ( + campaign_extension_setting_service, +) +from google.ads.googleads.v12.services.types import campaign_feed_service +from google.ads.googleads.v12.services.types import campaign_group_service +from google.ads.googleads.v12.services.types import campaign_label_service +from google.ads.googleads.v12.services.types import campaign_service +from google.ads.googleads.v12.services.types import campaign_shared_set_service +from google.ads.googleads.v12.services.types import conversion_action_service +from google.ads.googleads.v12.services.types import ( + conversion_custom_variable_service, +) +from google.ads.googleads.v12.services.types import ( + conversion_goal_campaign_config_service, +) +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_service, +) +from google.ads.googleads.v12.services.types import ( + conversion_value_rule_set_service, +) +from google.ads.googleads.v12.services.types import ( + custom_conversion_goal_service, +) +from google.ads.googleads.v12.services.types import customer_asset_service +from google.ads.googleads.v12.services.types import ( + customer_conversion_goal_service, +) +from google.ads.googleads.v12.services.types import customer_customizer_service +from google.ads.googleads.v12.services.types import ( + customer_extension_setting_service, +) +from google.ads.googleads.v12.services.types import customer_feed_service +from google.ads.googleads.v12.services.types import customer_label_service +from google.ads.googleads.v12.services.types import ( + customer_negative_criterion_service, +) +from google.ads.googleads.v12.services.types import customer_service +from google.ads.googleads.v12.services.types import customizer_attribute_service +from google.ads.googleads.v12.services.types import experiment_arm_service +from google.ads.googleads.v12.services.types import experiment_service +from google.ads.googleads.v12.services.types import extension_feed_item_service +from google.ads.googleads.v12.services.types import feed_item_service +from google.ads.googleads.v12.services.types import feed_item_set_link_service +from google.ads.googleads.v12.services.types import feed_item_set_service +from google.ads.googleads.v12.services.types import feed_item_target_service +from google.ads.googleads.v12.services.types import feed_mapping_service +from google.ads.googleads.v12.services.types import feed_service +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from google.ads.googleads.v12.services.types import ( + keyword_plan_ad_group_service, +) +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_keyword_service, +) +from google.ads.googleads.v12.services.types import ( + keyword_plan_campaign_service, +) +from google.ads.googleads.v12.services.types import keyword_plan_service +from google.ads.googleads.v12.services.types import label_service +from google.ads.googleads.v12.services.types import media_file_service +from google.ads.googleads.v12.services.types import remarketing_action_service +from google.ads.googleads.v12.services.types import shared_criterion_service +from google.ads.googleads.v12.services.types import shared_set_service +from google.ads.googleads.v12.services.types import ( + smart_campaign_setting_service, +) +from google.ads.googleads.v12.services.types import user_list_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "SearchGoogleAdsRequest", + "SearchGoogleAdsResponse", + "SearchGoogleAdsStreamRequest", + "SearchGoogleAdsStreamResponse", + "GoogleAdsRow", + "MutateGoogleAdsRequest", + "MutateGoogleAdsResponse", + "MutateOperation", + "MutateOperationResponse", + }, +) + + +class SearchGoogleAdsRequest(proto.Message): + r"""Request message for + [GoogleAdsService.Search][google.ads.googleads.v12.services.GoogleAdsService.Search]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + queried. + query (str): + Required. The query string. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. Use the value obtained + from ``next_page_token`` in the previous response in order + to request the next page of results. + page_size (int): + Number of elements to retrieve in a single + page. When too large a page is requested, the + server may decide to further limit the number of + returned resources. + validate_only (bool): + If true, the request is validated but not + executed. + return_total_results_count (bool): + If true, the total number of results that + match the query ignoring the LIMIT clause will + be included in the response. Default is false. + summary_row_setting (google.ads.googleads.v12.enums.types.SummaryRowSettingEnum.SummaryRowSetting): + Determines whether a summary row will be + returned. By default, summary row is not + returned. If requested, the summary row will be + sent in a response by itself after all other + query results are returned. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + query = proto.Field(proto.STRING, number=2,) + page_token = proto.Field(proto.STRING, number=3,) + page_size = proto.Field(proto.INT32, number=4,) + validate_only = proto.Field(proto.BOOL, number=5,) + return_total_results_count = proto.Field(proto.BOOL, number=7,) + summary_row_setting = proto.Field( + proto.ENUM, + number=8, + enum=gage_summary_row_setting.SummaryRowSettingEnum.SummaryRowSetting, + ) + + +class SearchGoogleAdsResponse(proto.Message): + r"""Response message for + [GoogleAdsService.Search][google.ads.googleads.v12.services.GoogleAdsService.Search]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.GoogleAdsRow]): + The list of rows that matched the query. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + total_results_count (int): + Total number of results that match the query + ignoring the LIMIT clause. + field_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that represents what fields were + requested by the user. + summary_row (google.ads.googleads.v12.services.types.GoogleAdsRow): + Summary row that contains summary of metrics + in results. Summary of metrics means aggregation + of metrics across all results, here aggregation + could be sum, average, rate, etc. + """ + + @property + def raw_page(self): + return self + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="GoogleAdsRow", + ) + next_page_token = proto.Field(proto.STRING, number=2,) + total_results_count = proto.Field(proto.INT64, number=3,) + field_mask = proto.Field( + proto.MESSAGE, number=5, message=field_mask_pb2.FieldMask, + ) + summary_row = proto.Field(proto.MESSAGE, number=6, message="GoogleAdsRow",) + + +class SearchGoogleAdsStreamRequest(proto.Message): + r"""Request message for + [GoogleAdsService.SearchStream][google.ads.googleads.v12.services.GoogleAdsService.SearchStream]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + queried. + query (str): + Required. The query string. + summary_row_setting (google.ads.googleads.v12.enums.types.SummaryRowSettingEnum.SummaryRowSetting): + Determines whether a summary row will be + returned. By default, summary row is not + returned. If requested, the summary row will be + sent in a response by itself after all other + query results are returned. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + query = proto.Field(proto.STRING, number=2,) + summary_row_setting = proto.Field( + proto.ENUM, + number=3, + enum=gage_summary_row_setting.SummaryRowSettingEnum.SummaryRowSetting, + ) + + +class SearchGoogleAdsStreamResponse(proto.Message): + r"""Response message for + [GoogleAdsService.SearchStream][google.ads.googleads.v12.services.GoogleAdsService.SearchStream]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.GoogleAdsRow]): + The list of rows that matched the query. + field_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that represents what fields were + requested by the user. + summary_row (google.ads.googleads.v12.services.types.GoogleAdsRow): + Summary row that contains summary of metrics + in results. Summary of metrics means aggregation + of metrics across all results, here aggregation + could be sum, average, rate, etc. + request_id (str): + The unique id of the request that is used for + debugging purposes. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="GoogleAdsRow", + ) + field_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + summary_row = proto.Field(proto.MESSAGE, number=3, message="GoogleAdsRow",) + request_id = proto.Field(proto.STRING, number=4,) + + +class GoogleAdsRow(proto.Message): + r"""A returned row from the query. + + Attributes: + account_budget (google.ads.googleads.v12.resources.types.AccountBudget): + The account budget in the query. + account_budget_proposal (google.ads.googleads.v12.resources.types.AccountBudgetProposal): + The account budget proposal referenced in the + query. + account_link (google.ads.googleads.v12.resources.types.AccountLink): + The AccountLink referenced in the query. + ad_group (google.ads.googleads.v12.resources.types.AdGroup): + The ad group referenced in the query. + ad_group_ad (google.ads.googleads.v12.resources.types.AdGroupAd): + The ad referenced in the query. + ad_group_ad_asset_combination_view (google.ads.googleads.v12.resources.types.AdGroupAdAssetCombinationView): + The ad group ad asset combination view in the + query. + ad_group_ad_asset_view (google.ads.googleads.v12.resources.types.AdGroupAdAssetView): + The ad group ad asset view in the query. + ad_group_ad_label (google.ads.googleads.v12.resources.types.AdGroupAdLabel): + The ad group ad label referenced in the + query. + ad_group_asset (google.ads.googleads.v12.resources.types.AdGroupAsset): + The ad group asset referenced in the query. + ad_group_asset_set (google.ads.googleads.v12.resources.types.AdGroupAssetSet): + The ad group asset set referenced in the + query. + ad_group_audience_view (google.ads.googleads.v12.resources.types.AdGroupAudienceView): + The ad group audience view referenced in the + query. + ad_group_bid_modifier (google.ads.googleads.v12.resources.types.AdGroupBidModifier): + The bid modifier referenced in the query. + ad_group_criterion (google.ads.googleads.v12.resources.types.AdGroupCriterion): + The criterion referenced in the query. + ad_group_criterion_customizer (google.ads.googleads.v12.resources.types.AdGroupCriterionCustomizer): + The ad group criterion customizer referenced + in the query. + ad_group_criterion_label (google.ads.googleads.v12.resources.types.AdGroupCriterionLabel): + The ad group criterion label referenced in + the query. + ad_group_criterion_simulation (google.ads.googleads.v12.resources.types.AdGroupCriterionSimulation): + The ad group criterion simulation referenced + in the query. + ad_group_customizer (google.ads.googleads.v12.resources.types.AdGroupCustomizer): + The ad group customizer referenced in the + query. + ad_group_extension_setting (google.ads.googleads.v12.resources.types.AdGroupExtensionSetting): + The ad group extension setting referenced in + the query. + ad_group_feed (google.ads.googleads.v12.resources.types.AdGroupFeed): + The ad group feed referenced in the query. + ad_group_label (google.ads.googleads.v12.resources.types.AdGroupLabel): + The ad group label referenced in the query. + ad_group_simulation (google.ads.googleads.v12.resources.types.AdGroupSimulation): + The ad group simulation referenced in the + query. + ad_parameter (google.ads.googleads.v12.resources.types.AdParameter): + The ad parameter referenced in the query. + age_range_view (google.ads.googleads.v12.resources.types.AgeRangeView): + The age range view referenced in the query. + ad_schedule_view (google.ads.googleads.v12.resources.types.AdScheduleView): + The ad schedule view referenced in the query. + domain_category (google.ads.googleads.v12.resources.types.DomainCategory): + The domain category referenced in the query. + asset (google.ads.googleads.v12.resources.types.Asset): + The asset referenced in the query. + asset_field_type_view (google.ads.googleads.v12.resources.types.AssetFieldTypeView): + The asset field type view referenced in the + query. + asset_group_asset (google.ads.googleads.v12.resources.types.AssetGroupAsset): + The asset group asset referenced in the + query. + asset_group_signal (google.ads.googleads.v12.resources.types.AssetGroupSignal): + The asset group signal referenced in the + query. + asset_group_listing_group_filter (google.ads.googleads.v12.resources.types.AssetGroupListingGroupFilter): + The asset group listing group filter + referenced in the query. + asset_group_product_group_view (google.ads.googleads.v12.resources.types.AssetGroupProductGroupView): + The asset group product group view referenced + in the query. + asset_group (google.ads.googleads.v12.resources.types.AssetGroup): + The asset group referenced in the query. + asset_set_asset (google.ads.googleads.v12.resources.types.AssetSetAsset): + The asset set asset referenced in the query. + asset_set (google.ads.googleads.v12.resources.types.AssetSet): + The asset set referenced in the query. + asset_set_type_view (google.ads.googleads.v12.resources.types.AssetSetTypeView): + The asset set type view referenced in the + query. + batch_job (google.ads.googleads.v12.resources.types.BatchJob): + The batch job referenced in the query. + bidding_data_exclusion (google.ads.googleads.v12.resources.types.BiddingDataExclusion): + The bidding data exclusion referenced in the + query. + bidding_seasonality_adjustment (google.ads.googleads.v12.resources.types.BiddingSeasonalityAdjustment): + The bidding seasonality adjustment referenced + in the query. + bidding_strategy (google.ads.googleads.v12.resources.types.BiddingStrategy): + The bidding strategy referenced in the query. + bidding_strategy_simulation (google.ads.googleads.v12.resources.types.BiddingStrategySimulation): + The bidding strategy simulation referenced in + the query. + billing_setup (google.ads.googleads.v12.resources.types.BillingSetup): + The billing setup referenced in the query. + call_view (google.ads.googleads.v12.resources.types.CallView): + The call view referenced in the query. + campaign_budget (google.ads.googleads.v12.resources.types.CampaignBudget): + The campaign budget referenced in the query. + campaign (google.ads.googleads.v12.resources.types.Campaign): + The campaign referenced in the query. + campaign_asset (google.ads.googleads.v12.resources.types.CampaignAsset): + The campaign asset referenced in the query. + campaign_asset_set (google.ads.googleads.v12.resources.types.CampaignAssetSet): + The campaign asset set referenced in the + query. + campaign_audience_view (google.ads.googleads.v12.resources.types.CampaignAudienceView): + The campaign audience view referenced in the + query. + campaign_bid_modifier (google.ads.googleads.v12.resources.types.CampaignBidModifier): + The campaign bid modifier referenced in the + query. + campaign_conversion_goal (google.ads.googleads.v12.resources.types.CampaignConversionGoal): + The CampaignConversionGoal referenced in the + query. + campaign_criterion (google.ads.googleads.v12.resources.types.CampaignCriterion): + The campaign criterion referenced in the + query. + campaign_criterion_simulation (google.ads.googleads.v12.resources.types.CampaignCriterionSimulation): + The campaign criterion simulation referenced + in the query. + campaign_customizer (google.ads.googleads.v12.resources.types.CampaignCustomizer): + The campaign customizer referenced in the + query. + campaign_draft (google.ads.googleads.v12.resources.types.CampaignDraft): + The campaign draft referenced in the query. + campaign_extension_setting (google.ads.googleads.v12.resources.types.CampaignExtensionSetting): + The campaign extension setting referenced in + the query. + campaign_feed (google.ads.googleads.v12.resources.types.CampaignFeed): + The campaign feed referenced in the query. + campaign_group (google.ads.googleads.v12.resources.types.CampaignGroup): + Campaign Group referenced in AWQL query. + campaign_label (google.ads.googleads.v12.resources.types.CampaignLabel): + The campaign label referenced in the query. + campaign_shared_set (google.ads.googleads.v12.resources.types.CampaignSharedSet): + Campaign Shared Set referenced in AWQL query. + campaign_simulation (google.ads.googleads.v12.resources.types.CampaignSimulation): + The campaign simulation referenced in the + query. + carrier_constant (google.ads.googleads.v12.resources.types.CarrierConstant): + The carrier constant referenced in the query. + change_event (google.ads.googleads.v12.resources.types.ChangeEvent): + The ChangeEvent referenced in the query. + change_status (google.ads.googleads.v12.resources.types.ChangeStatus): + The ChangeStatus referenced in the query. + combined_audience (google.ads.googleads.v12.resources.types.CombinedAudience): + The CombinedAudience referenced in the query. + audience (google.ads.googleads.v12.resources.types.Audience): + The Audience referenced in the query. + conversion_action (google.ads.googleads.v12.resources.types.ConversionAction): + The conversion action referenced in the + query. + conversion_custom_variable (google.ads.googleads.v12.resources.types.ConversionCustomVariable): + The conversion custom variable referenced in + the query. + conversion_goal_campaign_config (google.ads.googleads.v12.resources.types.ConversionGoalCampaignConfig): + The ConversionGoalCampaignConfig referenced + in the query. + conversion_value_rule (google.ads.googleads.v12.resources.types.ConversionValueRule): + The conversion value rule referenced in the + query. + conversion_value_rule_set (google.ads.googleads.v12.resources.types.ConversionValueRuleSet): + The conversion value rule set referenced in + the query. + click_view (google.ads.googleads.v12.resources.types.ClickView): + The ClickView referenced in the query. + currency_constant (google.ads.googleads.v12.resources.types.CurrencyConstant): + The currency constant referenced in the + query. + custom_audience (google.ads.googleads.v12.resources.types.CustomAudience): + The CustomAudience referenced in the query. + custom_conversion_goal (google.ads.googleads.v12.resources.types.CustomConversionGoal): + The CustomConversionGoal referenced in the + query. + custom_interest (google.ads.googleads.v12.resources.types.CustomInterest): + The CustomInterest referenced in the query. + customer (google.ads.googleads.v12.resources.types.Customer): + The customer referenced in the query. + customer_asset (google.ads.googleads.v12.resources.types.CustomerAsset): + The customer asset referenced in the query. + customer_asset_set (google.ads.googleads.v12.resources.types.CustomerAssetSet): + The customer asset set referenced in the + query. + accessible_bidding_strategy (google.ads.googleads.v12.resources.types.AccessibleBiddingStrategy): + The accessible bidding strategy referenced in + the query. + customer_customizer (google.ads.googleads.v12.resources.types.CustomerCustomizer): + The customer customizer referenced in the + query. + customer_manager_link (google.ads.googleads.v12.resources.types.CustomerManagerLink): + The CustomerManagerLink referenced in the + query. + customer_client_link (google.ads.googleads.v12.resources.types.CustomerClientLink): + The CustomerClientLink referenced in the + query. + customer_client (google.ads.googleads.v12.resources.types.CustomerClient): + The CustomerClient referenced in the query. + customer_conversion_goal (google.ads.googleads.v12.resources.types.CustomerConversionGoal): + The CustomerConversionGoal referenced in the + query. + customer_extension_setting (google.ads.googleads.v12.resources.types.CustomerExtensionSetting): + The customer extension setting referenced in + the query. + customer_feed (google.ads.googleads.v12.resources.types.CustomerFeed): + The customer feed referenced in the query. + customer_label (google.ads.googleads.v12.resources.types.CustomerLabel): + The customer label referenced in the query. + customer_negative_criterion (google.ads.googleads.v12.resources.types.CustomerNegativeCriterion): + The customer negative criterion referenced in + the query. + customer_user_access (google.ads.googleads.v12.resources.types.CustomerUserAccess): + The CustomerUserAccess referenced in the + query. + customer_user_access_invitation (google.ads.googleads.v12.resources.types.CustomerUserAccessInvitation): + The CustomerUserAccessInvitation referenced + in the query. + customizer_attribute (google.ads.googleads.v12.resources.types.CustomizerAttribute): + The customizer attribute referenced in the + query. + detail_placement_view (google.ads.googleads.v12.resources.types.DetailPlacementView): + The detail placement view referenced in the + query. + detailed_demographic (google.ads.googleads.v12.resources.types.DetailedDemographic): + The detailed demographic referenced in the + query. + display_keyword_view (google.ads.googleads.v12.resources.types.DisplayKeywordView): + The display keyword view referenced in the + query. + distance_view (google.ads.googleads.v12.resources.types.DistanceView): + The distance view referenced in the query. + dynamic_search_ads_search_term_view (google.ads.googleads.v12.resources.types.DynamicSearchAdsSearchTermView): + The dynamic search ads search term view + referenced in the query. + expanded_landing_page_view (google.ads.googleads.v12.resources.types.ExpandedLandingPageView): + The expanded landing page view referenced in + the query. + extension_feed_item (google.ads.googleads.v12.resources.types.ExtensionFeedItem): + The extension feed item referenced in the + query. + feed (google.ads.googleads.v12.resources.types.Feed): + The feed referenced in the query. + feed_item (google.ads.googleads.v12.resources.types.FeedItem): + The feed item referenced in the query. + feed_item_set (google.ads.googleads.v12.resources.types.FeedItemSet): + The feed item set referenced in the query. + feed_item_set_link (google.ads.googleads.v12.resources.types.FeedItemSetLink): + The feed item set link referenced in the + query. + feed_item_target (google.ads.googleads.v12.resources.types.FeedItemTarget): + The feed item target referenced in the query. + feed_mapping (google.ads.googleads.v12.resources.types.FeedMapping): + The feed mapping referenced in the query. + feed_placeholder_view (google.ads.googleads.v12.resources.types.FeedPlaceholderView): + The feed placeholder view referenced in the + query. + gender_view (google.ads.googleads.v12.resources.types.GenderView): + The gender view referenced in the query. + geo_target_constant (google.ads.googleads.v12.resources.types.GeoTargetConstant): + The geo target constant referenced in the + query. + geographic_view (google.ads.googleads.v12.resources.types.GeographicView): + The geographic view referenced in the query. + group_placement_view (google.ads.googleads.v12.resources.types.GroupPlacementView): + The group placement view referenced in the + query. + hotel_group_view (google.ads.googleads.v12.resources.types.HotelGroupView): + The hotel group view referenced in the query. + hotel_performance_view (google.ads.googleads.v12.resources.types.HotelPerformanceView): + The hotel performance view referenced in the + query. + hotel_reconciliation (google.ads.googleads.v12.resources.types.HotelReconciliation): + The hotel reconciliation referenced in the + query. + income_range_view (google.ads.googleads.v12.resources.types.IncomeRangeView): + The income range view referenced in the + query. + keyword_view (google.ads.googleads.v12.resources.types.KeywordView): + The keyword view referenced in the query. + keyword_plan (google.ads.googleads.v12.resources.types.KeywordPlan): + The keyword plan referenced in the query. + keyword_plan_campaign (google.ads.googleads.v12.resources.types.KeywordPlanCampaign): + The keyword plan campaign referenced in the + query. + keyword_plan_campaign_keyword (google.ads.googleads.v12.resources.types.KeywordPlanCampaignKeyword): + The keyword plan campaign keyword referenced + in the query. + keyword_plan_ad_group (google.ads.googleads.v12.resources.types.KeywordPlanAdGroup): + The keyword plan ad group referenced in the + query. + keyword_plan_ad_group_keyword (google.ads.googleads.v12.resources.types.KeywordPlanAdGroupKeyword): + The keyword plan ad group referenced in the + query. + keyword_theme_constant (google.ads.googleads.v12.resources.types.KeywordThemeConstant): + The keyword theme constant referenced in the + query. + label (google.ads.googleads.v12.resources.types.Label): + The label referenced in the query. + landing_page_view (google.ads.googleads.v12.resources.types.LandingPageView): + The landing page view referenced in the + query. + language_constant (google.ads.googleads.v12.resources.types.LanguageConstant): + The language constant referenced in the + query. + location_view (google.ads.googleads.v12.resources.types.LocationView): + The location view referenced in the query. + managed_placement_view (google.ads.googleads.v12.resources.types.ManagedPlacementView): + The managed placement view referenced in the + query. + media_file (google.ads.googleads.v12.resources.types.MediaFile): + The media file referenced in the query. + mobile_app_category_constant (google.ads.googleads.v12.resources.types.MobileAppCategoryConstant): + The mobile app category constant referenced + in the query. + mobile_device_constant (google.ads.googleads.v12.resources.types.MobileDeviceConstant): + The mobile device constant referenced in the + query. + offline_user_data_job (google.ads.googleads.v12.resources.types.OfflineUserDataJob): + The offline user data job referenced in the + query. + operating_system_version_constant (google.ads.googleads.v12.resources.types.OperatingSystemVersionConstant): + The operating system version constant + referenced in the query. + paid_organic_search_term_view (google.ads.googleads.v12.resources.types.PaidOrganicSearchTermView): + The paid organic search term view referenced + in the query. + parental_status_view (google.ads.googleads.v12.resources.types.ParentalStatusView): + The parental status view referenced in the + query. + per_store_view (google.ads.googleads.v12.resources.types.PerStoreView): + The per store view referenced in the query. + product_bidding_category_constant (google.ads.googleads.v12.resources.types.ProductBiddingCategoryConstant): + The Product Bidding Category referenced in + the query. + product_group_view (google.ads.googleads.v12.resources.types.ProductGroupView): + The product group view referenced in the + query. + recommendation (google.ads.googleads.v12.resources.types.Recommendation): + The recommendation referenced in the query. + search_term_view (google.ads.googleads.v12.resources.types.SearchTermView): + The search term view referenced in the query. + shared_criterion (google.ads.googleads.v12.resources.types.SharedCriterion): + The shared set referenced in the query. + shared_set (google.ads.googleads.v12.resources.types.SharedSet): + The shared set referenced in the query. + smart_campaign_setting (google.ads.googleads.v12.resources.types.SmartCampaignSetting): + The Smart campaign setting referenced in the + query. + shopping_performance_view (google.ads.googleads.v12.resources.types.ShoppingPerformanceView): + The shopping performance view referenced in + the query. + smart_campaign_search_term_view (google.ads.googleads.v12.resources.types.SmartCampaignSearchTermView): + The Smart campaign search term view + referenced in the query. + third_party_app_analytics_link (google.ads.googleads.v12.resources.types.ThirdPartyAppAnalyticsLink): + The AccountLink referenced in the query. + topic_view (google.ads.googleads.v12.resources.types.TopicView): + The topic view referenced in the query. + experiment (google.ads.googleads.v12.resources.types.Experiment): + The experiment referenced in the query. + experiment_arm (google.ads.googleads.v12.resources.types.ExperimentArm): + The experiment arm referenced in the query. + user_interest (google.ads.googleads.v12.resources.types.UserInterest): + The user interest referenced in the query. + life_event (google.ads.googleads.v12.resources.types.LifeEvent): + The life event referenced in the query. + user_list (google.ads.googleads.v12.resources.types.UserList): + The user list referenced in the query. + user_location_view (google.ads.googleads.v12.resources.types.UserLocationView): + The user location view referenced in the + query. + remarketing_action (google.ads.googleads.v12.resources.types.RemarketingAction): + The remarketing action referenced in the + query. + topic_constant (google.ads.googleads.v12.resources.types.TopicConstant): + The topic constant referenced in the query. + video (google.ads.googleads.v12.resources.types.Video): + The video referenced in the query. + webpage_view (google.ads.googleads.v12.resources.types.WebpageView): + The webpage view referenced in the query. + lead_form_submission_data (google.ads.googleads.v12.resources.types.LeadFormSubmissionData): + The lead form user submission referenced in + the query. + metrics (google.ads.googleads.v12.common.types.Metrics): + The metrics. + segments (google.ads.googleads.v12.common.types.Segments): + The segments. + """ + + account_budget = proto.Field( + proto.MESSAGE, number=42, message=gagr_account_budget.AccountBudget, + ) + account_budget_proposal = proto.Field( + proto.MESSAGE, + number=43, + message=gagr_account_budget_proposal.AccountBudgetProposal, + ) + account_link = proto.Field( + proto.MESSAGE, number=143, message=gagr_account_link.AccountLink, + ) + ad_group = proto.Field( + proto.MESSAGE, number=3, message=gagr_ad_group.AdGroup, + ) + ad_group_ad = proto.Field( + proto.MESSAGE, number=16, message=gagr_ad_group_ad.AdGroupAd, + ) + ad_group_ad_asset_combination_view = proto.Field( + proto.MESSAGE, + number=193, + message=gagr_ad_group_ad_asset_combination_view.AdGroupAdAssetCombinationView, + ) + ad_group_ad_asset_view = proto.Field( + proto.MESSAGE, + number=131, + message=gagr_ad_group_ad_asset_view.AdGroupAdAssetView, + ) + ad_group_ad_label = proto.Field( + proto.MESSAGE, + number=120, + message=gagr_ad_group_ad_label.AdGroupAdLabel, + ) + ad_group_asset = proto.Field( + proto.MESSAGE, number=154, message=gagr_ad_group_asset.AdGroupAsset, + ) + ad_group_asset_set = proto.Field( + proto.MESSAGE, + number=196, + message=gagr_ad_group_asset_set.AdGroupAssetSet, + ) + ad_group_audience_view = proto.Field( + proto.MESSAGE, + number=57, + message=gagr_ad_group_audience_view.AdGroupAudienceView, + ) + ad_group_bid_modifier = proto.Field( + proto.MESSAGE, + number=24, + message=gagr_ad_group_bid_modifier.AdGroupBidModifier, + ) + ad_group_criterion = proto.Field( + proto.MESSAGE, + number=17, + message=gagr_ad_group_criterion.AdGroupCriterion, + ) + ad_group_criterion_customizer = proto.Field( + proto.MESSAGE, + number=187, + message=gagr_ad_group_criterion_customizer.AdGroupCriterionCustomizer, + ) + ad_group_criterion_label = proto.Field( + proto.MESSAGE, + number=121, + message=gagr_ad_group_criterion_label.AdGroupCriterionLabel, + ) + ad_group_criterion_simulation = proto.Field( + proto.MESSAGE, + number=110, + message=gagr_ad_group_criterion_simulation.AdGroupCriterionSimulation, + ) + ad_group_customizer = proto.Field( + proto.MESSAGE, + number=185, + message=gagr_ad_group_customizer.AdGroupCustomizer, + ) + ad_group_extension_setting = proto.Field( + proto.MESSAGE, + number=112, + message=gagr_ad_group_extension_setting.AdGroupExtensionSetting, + ) + ad_group_feed = proto.Field( + proto.MESSAGE, number=67, message=gagr_ad_group_feed.AdGroupFeed, + ) + ad_group_label = proto.Field( + proto.MESSAGE, number=115, message=gagr_ad_group_label.AdGroupLabel, + ) + ad_group_simulation = proto.Field( + proto.MESSAGE, + number=107, + message=gagr_ad_group_simulation.AdGroupSimulation, + ) + ad_parameter = proto.Field( + proto.MESSAGE, number=130, message=gagr_ad_parameter.AdParameter, + ) + age_range_view = proto.Field( + proto.MESSAGE, number=48, message=gagr_age_range_view.AgeRangeView, + ) + ad_schedule_view = proto.Field( + proto.MESSAGE, number=89, message=gagr_ad_schedule_view.AdScheduleView, + ) + domain_category = proto.Field( + proto.MESSAGE, number=91, message=gagr_domain_category.DomainCategory, + ) + asset = proto.Field(proto.MESSAGE, number=105, message=gagr_asset.Asset,) + asset_field_type_view = proto.Field( + proto.MESSAGE, + number=168, + message=gagr_asset_field_type_view.AssetFieldTypeView, + ) + asset_group_asset = proto.Field( + proto.MESSAGE, + number=173, + message=gagr_asset_group_asset.AssetGroupAsset, + ) + asset_group_signal = proto.Field( + proto.MESSAGE, + number=191, + message=gagr_asset_group_signal.AssetGroupSignal, + ) + asset_group_listing_group_filter = proto.Field( + proto.MESSAGE, + number=182, + message=gagr_asset_group_listing_group_filter.AssetGroupListingGroupFilter, + ) + asset_group_product_group_view = proto.Field( + proto.MESSAGE, + number=189, + message=gagr_asset_group_product_group_view.AssetGroupProductGroupView, + ) + asset_group = proto.Field( + proto.MESSAGE, number=172, message=gagr_asset_group.AssetGroup, + ) + asset_set_asset = proto.Field( + proto.MESSAGE, number=180, message=gagr_asset_set_asset.AssetSetAsset, + ) + asset_set = proto.Field( + proto.MESSAGE, number=179, message=gagr_asset_set.AssetSet, + ) + asset_set_type_view = proto.Field( + proto.MESSAGE, + number=197, + message=gagr_asset_set_type_view.AssetSetTypeView, + ) + batch_job = proto.Field( + proto.MESSAGE, number=139, message=gagr_batch_job.BatchJob, + ) + bidding_data_exclusion = proto.Field( + proto.MESSAGE, + number=159, + message=gagr_bidding_data_exclusion.BiddingDataExclusion, + ) + bidding_seasonality_adjustment = proto.Field( + proto.MESSAGE, + number=160, + message=gagr_bidding_seasonality_adjustment.BiddingSeasonalityAdjustment, + ) + bidding_strategy = proto.Field( + proto.MESSAGE, number=18, message=gagr_bidding_strategy.BiddingStrategy, + ) + bidding_strategy_simulation = proto.Field( + proto.MESSAGE, + number=158, + message=gagr_bidding_strategy_simulation.BiddingStrategySimulation, + ) + billing_setup = proto.Field( + proto.MESSAGE, number=41, message=gagr_billing_setup.BillingSetup, + ) + call_view = proto.Field( + proto.MESSAGE, number=152, message=gagr_call_view.CallView, + ) + campaign_budget = proto.Field( + proto.MESSAGE, number=19, message=gagr_campaign_budget.CampaignBudget, + ) + campaign = proto.Field( + proto.MESSAGE, number=2, message=gagr_campaign.Campaign, + ) + campaign_asset = proto.Field( + proto.MESSAGE, number=142, message=gagr_campaign_asset.CampaignAsset, + ) + campaign_asset_set = proto.Field( + proto.MESSAGE, + number=181, + message=gagr_campaign_asset_set.CampaignAssetSet, + ) + campaign_audience_view = proto.Field( + proto.MESSAGE, + number=69, + message=gagr_campaign_audience_view.CampaignAudienceView, + ) + campaign_bid_modifier = proto.Field( + proto.MESSAGE, + number=26, + message=gagr_campaign_bid_modifier.CampaignBidModifier, + ) + campaign_conversion_goal = proto.Field( + proto.MESSAGE, + number=175, + message=gagr_campaign_conversion_goal.CampaignConversionGoal, + ) + campaign_criterion = proto.Field( + proto.MESSAGE, + number=20, + message=gagr_campaign_criterion.CampaignCriterion, + ) + campaign_criterion_simulation = proto.Field( + proto.MESSAGE, + number=111, + message=gagr_campaign_criterion_simulation.CampaignCriterionSimulation, + ) + campaign_customizer = proto.Field( + proto.MESSAGE, + number=186, + message=gagr_campaign_customizer.CampaignCustomizer, + ) + campaign_draft = proto.Field( + proto.MESSAGE, number=49, message=gagr_campaign_draft.CampaignDraft, + ) + campaign_extension_setting = proto.Field( + proto.MESSAGE, + number=113, + message=gagr_campaign_extension_setting.CampaignExtensionSetting, + ) + campaign_feed = proto.Field( + proto.MESSAGE, number=63, message=gagr_campaign_feed.CampaignFeed, + ) + campaign_group = proto.Field( + proto.MESSAGE, number=25, message=gagr_campaign_group.CampaignGroup, + ) + campaign_label = proto.Field( + proto.MESSAGE, number=108, message=gagr_campaign_label.CampaignLabel, + ) + campaign_shared_set = proto.Field( + proto.MESSAGE, + number=30, + message=gagr_campaign_shared_set.CampaignSharedSet, + ) + campaign_simulation = proto.Field( + proto.MESSAGE, + number=157, + message=gagr_campaign_simulation.CampaignSimulation, + ) + carrier_constant = proto.Field( + proto.MESSAGE, number=66, message=gagr_carrier_constant.CarrierConstant, + ) + change_event = proto.Field( + proto.MESSAGE, number=145, message=gagr_change_event.ChangeEvent, + ) + change_status = proto.Field( + proto.MESSAGE, number=37, message=gagr_change_status.ChangeStatus, + ) + combined_audience = proto.Field( + proto.MESSAGE, + number=148, + message=gagr_combined_audience.CombinedAudience, + ) + audience = proto.Field( + proto.MESSAGE, number=190, message=gagr_audience.Audience, + ) + conversion_action = proto.Field( + proto.MESSAGE, + number=103, + message=gagr_conversion_action.ConversionAction, + ) + conversion_custom_variable = proto.Field( + proto.MESSAGE, + number=153, + message=gagr_conversion_custom_variable.ConversionCustomVariable, + ) + conversion_goal_campaign_config = proto.Field( + proto.MESSAGE, + number=177, + message=gagr_conversion_goal_campaign_config.ConversionGoalCampaignConfig, + ) + conversion_value_rule = proto.Field( + proto.MESSAGE, + number=164, + message=gagr_conversion_value_rule.ConversionValueRule, + ) + conversion_value_rule_set = proto.Field( + proto.MESSAGE, + number=165, + message=gagr_conversion_value_rule_set.ConversionValueRuleSet, + ) + click_view = proto.Field( + proto.MESSAGE, number=122, message=gagr_click_view.ClickView, + ) + currency_constant = proto.Field( + proto.MESSAGE, + number=134, + message=gagr_currency_constant.CurrencyConstant, + ) + custom_audience = proto.Field( + proto.MESSAGE, number=147, message=gagr_custom_audience.CustomAudience, + ) + custom_conversion_goal = proto.Field( + proto.MESSAGE, + number=176, + message=gagr_custom_conversion_goal.CustomConversionGoal, + ) + custom_interest = proto.Field( + proto.MESSAGE, number=104, message=gagr_custom_interest.CustomInterest, + ) + customer = proto.Field( + proto.MESSAGE, number=1, message=gagr_customer.Customer, + ) + customer_asset = proto.Field( + proto.MESSAGE, number=155, message=gagr_customer_asset.CustomerAsset, + ) + customer_asset_set = proto.Field( + proto.MESSAGE, + number=195, + message=gagr_customer_asset_set.CustomerAssetSet, + ) + accessible_bidding_strategy = proto.Field( + proto.MESSAGE, + number=169, + message=gagr_accessible_bidding_strategy.AccessibleBiddingStrategy, + ) + customer_customizer = proto.Field( + proto.MESSAGE, + number=184, + message=gagr_customer_customizer.CustomerCustomizer, + ) + customer_manager_link = proto.Field( + proto.MESSAGE, + number=61, + message=gagr_customer_manager_link.CustomerManagerLink, + ) + customer_client_link = proto.Field( + proto.MESSAGE, + number=62, + message=gagr_customer_client_link.CustomerClientLink, + ) + customer_client = proto.Field( + proto.MESSAGE, number=70, message=gagr_customer_client.CustomerClient, + ) + customer_conversion_goal = proto.Field( + proto.MESSAGE, + number=174, + message=gagr_customer_conversion_goal.CustomerConversionGoal, + ) + customer_extension_setting = proto.Field( + proto.MESSAGE, + number=114, + message=gagr_customer_extension_setting.CustomerExtensionSetting, + ) + customer_feed = proto.Field( + proto.MESSAGE, number=64, message=gagr_customer_feed.CustomerFeed, + ) + customer_label = proto.Field( + proto.MESSAGE, number=124, message=gagr_customer_label.CustomerLabel, + ) + customer_negative_criterion = proto.Field( + proto.MESSAGE, + number=88, + message=gagr_customer_negative_criterion.CustomerNegativeCriterion, + ) + customer_user_access = proto.Field( + proto.MESSAGE, + number=146, + message=gagr_customer_user_access.CustomerUserAccess, + ) + customer_user_access_invitation = proto.Field( + proto.MESSAGE, + number=150, + message=gagr_customer_user_access_invitation.CustomerUserAccessInvitation, + ) + customizer_attribute = proto.Field( + proto.MESSAGE, + number=178, + message=gagr_customizer_attribute.CustomizerAttribute, + ) + detail_placement_view = proto.Field( + proto.MESSAGE, + number=118, + message=gagr_detail_placement_view.DetailPlacementView, + ) + detailed_demographic = proto.Field( + proto.MESSAGE, + number=166, + message=gagr_detailed_demographic.DetailedDemographic, + ) + display_keyword_view = proto.Field( + proto.MESSAGE, + number=47, + message=gagr_display_keyword_view.DisplayKeywordView, + ) + distance_view = proto.Field( + proto.MESSAGE, number=132, message=gagr_distance_view.DistanceView, + ) + dynamic_search_ads_search_term_view = proto.Field( + proto.MESSAGE, + number=106, + message=gagr_dynamic_search_ads_search_term_view.DynamicSearchAdsSearchTermView, + ) + expanded_landing_page_view = proto.Field( + proto.MESSAGE, + number=128, + message=gagr_expanded_landing_page_view.ExpandedLandingPageView, + ) + extension_feed_item = proto.Field( + proto.MESSAGE, + number=85, + message=gagr_extension_feed_item.ExtensionFeedItem, + ) + feed = proto.Field(proto.MESSAGE, number=46, message=gagr_feed.Feed,) + feed_item = proto.Field( + proto.MESSAGE, number=50, message=gagr_feed_item.FeedItem, + ) + feed_item_set = proto.Field( + proto.MESSAGE, number=149, message=gagr_feed_item_set.FeedItemSet, + ) + feed_item_set_link = proto.Field( + proto.MESSAGE, + number=151, + message=gagr_feed_item_set_link.FeedItemSetLink, + ) + feed_item_target = proto.Field( + proto.MESSAGE, number=116, message=gagr_feed_item_target.FeedItemTarget, + ) + feed_mapping = proto.Field( + proto.MESSAGE, number=58, message=gagr_feed_mapping.FeedMapping, + ) + feed_placeholder_view = proto.Field( + proto.MESSAGE, + number=97, + message=gagr_feed_placeholder_view.FeedPlaceholderView, + ) + gender_view = proto.Field( + proto.MESSAGE, number=40, message=gagr_gender_view.GenderView, + ) + geo_target_constant = proto.Field( + proto.MESSAGE, + number=23, + message=gagr_geo_target_constant.GeoTargetConstant, + ) + geographic_view = proto.Field( + proto.MESSAGE, number=125, message=gagr_geographic_view.GeographicView, + ) + group_placement_view = proto.Field( + proto.MESSAGE, + number=119, + message=gagr_group_placement_view.GroupPlacementView, + ) + hotel_group_view = proto.Field( + proto.MESSAGE, number=51, message=gagr_hotel_group_view.HotelGroupView, + ) + hotel_performance_view = proto.Field( + proto.MESSAGE, + number=71, + message=gagr_hotel_performance_view.HotelPerformanceView, + ) + hotel_reconciliation = proto.Field( + proto.MESSAGE, + number=188, + message=gagr_hotel_reconciliation.HotelReconciliation, + ) + income_range_view = proto.Field( + proto.MESSAGE, + number=138, + message=gagr_income_range_view.IncomeRangeView, + ) + keyword_view = proto.Field( + proto.MESSAGE, number=21, message=gagr_keyword_view.KeywordView, + ) + keyword_plan = proto.Field( + proto.MESSAGE, number=32, message=gagr_keyword_plan.KeywordPlan, + ) + keyword_plan_campaign = proto.Field( + proto.MESSAGE, + number=33, + message=gagr_keyword_plan_campaign.KeywordPlanCampaign, + ) + keyword_plan_campaign_keyword = proto.Field( + proto.MESSAGE, + number=140, + message=gagr_keyword_plan_campaign_keyword.KeywordPlanCampaignKeyword, + ) + keyword_plan_ad_group = proto.Field( + proto.MESSAGE, + number=35, + message=gagr_keyword_plan_ad_group.KeywordPlanAdGroup, + ) + keyword_plan_ad_group_keyword = proto.Field( + proto.MESSAGE, + number=141, + message=gagr_keyword_plan_ad_group_keyword.KeywordPlanAdGroupKeyword, + ) + keyword_theme_constant = proto.Field( + proto.MESSAGE, + number=163, + message=gagr_keyword_theme_constant.KeywordThemeConstant, + ) + label = proto.Field(proto.MESSAGE, number=52, message=gagr_label.Label,) + landing_page_view = proto.Field( + proto.MESSAGE, + number=126, + message=gagr_landing_page_view.LandingPageView, + ) + language_constant = proto.Field( + proto.MESSAGE, + number=55, + message=gagr_language_constant.LanguageConstant, + ) + location_view = proto.Field( + proto.MESSAGE, number=123, message=gagr_location_view.LocationView, + ) + managed_placement_view = proto.Field( + proto.MESSAGE, + number=53, + message=gagr_managed_placement_view.ManagedPlacementView, + ) + media_file = proto.Field( + proto.MESSAGE, number=90, message=gagr_media_file.MediaFile, + ) + mobile_app_category_constant = proto.Field( + proto.MESSAGE, + number=87, + message=gagr_mobile_app_category_constant.MobileAppCategoryConstant, + ) + mobile_device_constant = proto.Field( + proto.MESSAGE, + number=98, + message=gagr_mobile_device_constant.MobileDeviceConstant, + ) + offline_user_data_job = proto.Field( + proto.MESSAGE, + number=137, + message=gagr_offline_user_data_job.OfflineUserDataJob, + ) + operating_system_version_constant = proto.Field( + proto.MESSAGE, + number=86, + message=gagr_operating_system_version_constant.OperatingSystemVersionConstant, + ) + paid_organic_search_term_view = proto.Field( + proto.MESSAGE, + number=129, + message=gagr_paid_organic_search_term_view.PaidOrganicSearchTermView, + ) + parental_status_view = proto.Field( + proto.MESSAGE, + number=45, + message=gagr_parental_status_view.ParentalStatusView, + ) + per_store_view = proto.Field( + proto.MESSAGE, number=198, message=gagr_per_store_view.PerStoreView, + ) + product_bidding_category_constant = proto.Field( + proto.MESSAGE, + number=109, + message=gagr_product_bidding_category_constant.ProductBiddingCategoryConstant, + ) + product_group_view = proto.Field( + proto.MESSAGE, + number=54, + message=gagr_product_group_view.ProductGroupView, + ) + recommendation = proto.Field( + proto.MESSAGE, number=22, message=gagr_recommendation.Recommendation, + ) + search_term_view = proto.Field( + proto.MESSAGE, number=68, message=gagr_search_term_view.SearchTermView, + ) + shared_criterion = proto.Field( + proto.MESSAGE, number=29, message=gagr_shared_criterion.SharedCriterion, + ) + shared_set = proto.Field( + proto.MESSAGE, number=27, message=gagr_shared_set.SharedSet, + ) + smart_campaign_setting = proto.Field( + proto.MESSAGE, + number=167, + message=gagr_smart_campaign_setting.SmartCampaignSetting, + ) + shopping_performance_view = proto.Field( + proto.MESSAGE, + number=117, + message=gagr_shopping_performance_view.ShoppingPerformanceView, + ) + smart_campaign_search_term_view = proto.Field( + proto.MESSAGE, + number=170, + message=gagr_smart_campaign_search_term_view.SmartCampaignSearchTermView, + ) + third_party_app_analytics_link = proto.Field( + proto.MESSAGE, + number=144, + message=gagr_third_party_app_analytics_link.ThirdPartyAppAnalyticsLink, + ) + topic_view = proto.Field( + proto.MESSAGE, number=44, message=gagr_topic_view.TopicView, + ) + experiment = proto.Field( + proto.MESSAGE, number=133, message=gagr_experiment.Experiment, + ) + experiment_arm = proto.Field( + proto.MESSAGE, number=183, message=gagr_experiment_arm.ExperimentArm, + ) + user_interest = proto.Field( + proto.MESSAGE, number=59, message=gagr_user_interest.UserInterest, + ) + life_event = proto.Field( + proto.MESSAGE, number=161, message=gagr_life_event.LifeEvent, + ) + user_list = proto.Field( + proto.MESSAGE, number=38, message=gagr_user_list.UserList, + ) + user_location_view = proto.Field( + proto.MESSAGE, + number=135, + message=gagr_user_location_view.UserLocationView, + ) + remarketing_action = proto.Field( + proto.MESSAGE, + number=60, + message=gagr_remarketing_action.RemarketingAction, + ) + topic_constant = proto.Field( + proto.MESSAGE, number=31, message=gagr_topic_constant.TopicConstant, + ) + video = proto.Field(proto.MESSAGE, number=39, message=gagr_video.Video,) + webpage_view = proto.Field( + proto.MESSAGE, number=162, message=gagr_webpage_view.WebpageView, + ) + lead_form_submission_data = proto.Field( + proto.MESSAGE, + number=192, + message=gagr_lead_form_submission_data.LeadFormSubmissionData, + ) + metrics = proto.Field( + proto.MESSAGE, number=4, message=gagc_metrics.Metrics, + ) + segments = proto.Field( + proto.MESSAGE, number=102, message=gagc_segments.Segments, + ) + + +class MutateGoogleAdsRequest(proto.Message): + r"""Request message for + [GoogleAdsService.Mutate][google.ads.googleads.v12.services.GoogleAdsService.Mutate]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + resources are being modified. + mutate_operations (Sequence[google.ads.googleads.v12.services.types.MutateOperation]): + Required. The list of operations to perform + on individual resources. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + The mutable resource will only be returned if + the resource has the appropriate response field. + For example, MutateCampaignResult.campaign. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + mutate_operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class MutateGoogleAdsResponse(proto.Message): + r"""Response message for + [GoogleAdsService.Mutate][google.ads.googleads.v12.services.GoogleAdsService.Mutate]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + mutate_operation_responses (Sequence[google.ads.googleads.v12.services.types.MutateOperationResponse]): + All responses for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + mutate_operation_responses = proto.RepeatedField( + proto.MESSAGE, number=1, message="MutateOperationResponse", + ) + + +class MutateOperation(proto.Message): + r"""A single operation (create, update, remove) on a resource. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + ad_group_ad_label_operation (google.ads.googleads.v12.services.types.AdGroupAdLabelOperation): + An ad group ad label mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_ad_operation (google.ads.googleads.v12.services.types.AdGroupAdOperation): + An ad group ad mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_asset_operation (google.ads.googleads.v12.services.types.AdGroupAssetOperation): + An ad group asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_bid_modifier_operation (google.ads.googleads.v12.services.types.AdGroupBidModifierOperation): + An ad group bid modifier mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_criterion_customizer_operation (google.ads.googleads.v12.services.types.AdGroupCriterionCustomizerOperation): + An ad group criterion customizer mutate + operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_criterion_label_operation (google.ads.googleads.v12.services.types.AdGroupCriterionLabelOperation): + An ad group criterion label mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_criterion_operation (google.ads.googleads.v12.services.types.AdGroupCriterionOperation): + An ad group criterion mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_customizer_operation (google.ads.googleads.v12.services.types.AdGroupCustomizerOperation): + An ad group customizer mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_extension_setting_operation (google.ads.googleads.v12.services.types.AdGroupExtensionSettingOperation): + An ad group extension setting mutate + operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_feed_operation (google.ads.googleads.v12.services.types.AdGroupFeedOperation): + An ad group feed mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_label_operation (google.ads.googleads.v12.services.types.AdGroupLabelOperation): + An ad group label mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_group_operation (google.ads.googleads.v12.services.types.AdGroupOperation): + An ad group mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_operation (google.ads.googleads.v12.services.types.AdOperation): + An ad mutate operation. + + This field is a member of `oneof`_ ``operation``. + ad_parameter_operation (google.ads.googleads.v12.services.types.AdParameterOperation): + An ad parameter mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_operation (google.ads.googleads.v12.services.types.AssetOperation): + An asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_group_asset_operation (google.ads.googleads.v12.services.types.AssetGroupAssetOperation): + An asset group asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_group_listing_group_filter_operation (google.ads.googleads.v12.services.types.AssetGroupListingGroupFilterOperation): + An asset group listing group filter mutate + operation. + + This field is a member of `oneof`_ ``operation``. + asset_group_signal_operation (google.ads.googleads.v12.services.types.AssetGroupSignalOperation): + An asset group signal mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_group_operation (google.ads.googleads.v12.services.types.AssetGroupOperation): + An asset group mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_set_asset_operation (google.ads.googleads.v12.services.types.AssetSetAssetOperation): + An asset set asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + asset_set_operation (google.ads.googleads.v12.services.types.AssetSetOperation): + An asset set mutate operation. + + This field is a member of `oneof`_ ``operation``. + audience_operation (google.ads.googleads.v12.services.types.AudienceOperation): + An audience mutate operation. + + This field is a member of `oneof`_ ``operation``. + bidding_data_exclusion_operation (google.ads.googleads.v12.services.types.BiddingDataExclusionOperation): + A bidding data exclusion mutate operation. + + This field is a member of `oneof`_ ``operation``. + bidding_seasonality_adjustment_operation (google.ads.googleads.v12.services.types.BiddingSeasonalityAdjustmentOperation): + A bidding seasonality adjustment mutate + operation. + + This field is a member of `oneof`_ ``operation``. + bidding_strategy_operation (google.ads.googleads.v12.services.types.BiddingStrategyOperation): + A bidding strategy mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_asset_operation (google.ads.googleads.v12.services.types.CampaignAssetOperation): + A campaign asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_asset_set_operation (google.ads.googleads.v12.services.types.CampaignAssetSetOperation): + A campaign asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_bid_modifier_operation (google.ads.googleads.v12.services.types.CampaignBidModifierOperation): + A campaign bid modifier mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_budget_operation (google.ads.googleads.v12.services.types.CampaignBudgetOperation): + A campaign budget mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_conversion_goal_operation (google.ads.googleads.v12.services.types.CampaignConversionGoalOperation): + A campaign conversion goal mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_criterion_operation (google.ads.googleads.v12.services.types.CampaignCriterionOperation): + A campaign criterion mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_customizer_operation (google.ads.googleads.v12.services.types.CampaignCustomizerOperation): + A campaign customizer mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_draft_operation (google.ads.googleads.v12.services.types.CampaignDraftOperation): + A campaign draft mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_extension_setting_operation (google.ads.googleads.v12.services.types.CampaignExtensionSettingOperation): + A campaign extension setting mutate + operation. + + This field is a member of `oneof`_ ``operation``. + campaign_feed_operation (google.ads.googleads.v12.services.types.CampaignFeedOperation): + A campaign feed mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_group_operation (google.ads.googleads.v12.services.types.CampaignGroupOperation): + A campaign group mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_label_operation (google.ads.googleads.v12.services.types.CampaignLabelOperation): + A campaign label mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_operation (google.ads.googleads.v12.services.types.CampaignOperation): + A campaign mutate operation. + + This field is a member of `oneof`_ ``operation``. + campaign_shared_set_operation (google.ads.googleads.v12.services.types.CampaignSharedSetOperation): + A campaign shared set mutate operation. + + This field is a member of `oneof`_ ``operation``. + conversion_action_operation (google.ads.googleads.v12.services.types.ConversionActionOperation): + A conversion action mutate operation. + + This field is a member of `oneof`_ ``operation``. + conversion_custom_variable_operation (google.ads.googleads.v12.services.types.ConversionCustomVariableOperation): + A conversion custom variable mutate + operation. + + This field is a member of `oneof`_ ``operation``. + conversion_goal_campaign_config_operation (google.ads.googleads.v12.services.types.ConversionGoalCampaignConfigOperation): + A conversion goal campaign config mutate + operation. + + This field is a member of `oneof`_ ``operation``. + conversion_value_rule_operation (google.ads.googleads.v12.services.types.ConversionValueRuleOperation): + A conversion value rule mutate operation. + + This field is a member of `oneof`_ ``operation``. + conversion_value_rule_set_operation (google.ads.googleads.v12.services.types.ConversionValueRuleSetOperation): + A conversion value rule set mutate operation. + + This field is a member of `oneof`_ ``operation``. + custom_conversion_goal_operation (google.ads.googleads.v12.services.types.CustomConversionGoalOperation): + A custom conversion goal mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_asset_operation (google.ads.googleads.v12.services.types.CustomerAssetOperation): + A customer asset mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_conversion_goal_operation (google.ads.googleads.v12.services.types.CustomerConversionGoalOperation): + A customer conversion goal mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_customizer_operation (google.ads.googleads.v12.services.types.CustomerCustomizerOperation): + A customer customizer mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_extension_setting_operation (google.ads.googleads.v12.services.types.CustomerExtensionSettingOperation): + A customer extension setting mutate + operation. + + This field is a member of `oneof`_ ``operation``. + customer_feed_operation (google.ads.googleads.v12.services.types.CustomerFeedOperation): + A customer feed mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_label_operation (google.ads.googleads.v12.services.types.CustomerLabelOperation): + A customer label mutate operation. + + This field is a member of `oneof`_ ``operation``. + customer_negative_criterion_operation (google.ads.googleads.v12.services.types.CustomerNegativeCriterionOperation): + A customer negative criterion mutate + operation. + + This field is a member of `oneof`_ ``operation``. + customer_operation (google.ads.googleads.v12.services.types.CustomerOperation): + A customer mutate operation. + + This field is a member of `oneof`_ ``operation``. + customizer_attribute_operation (google.ads.googleads.v12.services.types.CustomizerAttributeOperation): + A customizer attribute mutate operation. + + This field is a member of `oneof`_ ``operation``. + experiment_operation (google.ads.googleads.v12.services.types.ExperimentOperation): + An experiment mutate operation. + + This field is a member of `oneof`_ ``operation``. + experiment_arm_operation (google.ads.googleads.v12.services.types.ExperimentArmOperation): + An experiment arm mutate operation. + + This field is a member of `oneof`_ ``operation``. + extension_feed_item_operation (google.ads.googleads.v12.services.types.ExtensionFeedItemOperation): + An extension feed item mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_item_operation (google.ads.googleads.v12.services.types.FeedItemOperation): + A feed item mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_item_set_operation (google.ads.googleads.v12.services.types.FeedItemSetOperation): + A feed item set mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_item_set_link_operation (google.ads.googleads.v12.services.types.FeedItemSetLinkOperation): + A feed item set link mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_item_target_operation (google.ads.googleads.v12.services.types.FeedItemTargetOperation): + A feed item target mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_mapping_operation (google.ads.googleads.v12.services.types.FeedMappingOperation): + A feed mapping mutate operation. + + This field is a member of `oneof`_ ``operation``. + feed_operation (google.ads.googleads.v12.services.types.FeedOperation): + A feed mutate operation. + + This field is a member of `oneof`_ ``operation``. + keyword_plan_ad_group_operation (google.ads.googleads.v12.services.types.KeywordPlanAdGroupOperation): + A keyword plan ad group operation. + + This field is a member of `oneof`_ ``operation``. + keyword_plan_ad_group_keyword_operation (google.ads.googleads.v12.services.types.KeywordPlanAdGroupKeywordOperation): + A keyword plan ad group keyword operation. + + This field is a member of `oneof`_ ``operation``. + keyword_plan_campaign_keyword_operation (google.ads.googleads.v12.services.types.KeywordPlanCampaignKeywordOperation): + A keyword plan campaign keyword operation. + + This field is a member of `oneof`_ ``operation``. + keyword_plan_campaign_operation (google.ads.googleads.v12.services.types.KeywordPlanCampaignOperation): + A keyword plan campaign operation. + + This field is a member of `oneof`_ ``operation``. + keyword_plan_operation (google.ads.googleads.v12.services.types.KeywordPlanOperation): + A keyword plan operation. + + This field is a member of `oneof`_ ``operation``. + label_operation (google.ads.googleads.v12.services.types.LabelOperation): + A label mutate operation. + + This field is a member of `oneof`_ ``operation``. + media_file_operation (google.ads.googleads.v12.services.types.MediaFileOperation): + A media file mutate operation. + + This field is a member of `oneof`_ ``operation``. + remarketing_action_operation (google.ads.googleads.v12.services.types.RemarketingActionOperation): + A remarketing action mutate operation. + + This field is a member of `oneof`_ ``operation``. + shared_criterion_operation (google.ads.googleads.v12.services.types.SharedCriterionOperation): + A shared criterion mutate operation. + + This field is a member of `oneof`_ ``operation``. + shared_set_operation (google.ads.googleads.v12.services.types.SharedSetOperation): + A shared set mutate operation. + + This field is a member of `oneof`_ ``operation``. + smart_campaign_setting_operation (google.ads.googleads.v12.services.types.SmartCampaignSettingOperation): + A Smart campaign setting mutate operation. + + This field is a member of `oneof`_ ``operation``. + user_list_operation (google.ads.googleads.v12.services.types.UserListOperation): + A user list mutate operation. + + This field is a member of `oneof`_ ``operation``. + """ + + ad_group_ad_label_operation = proto.Field( + proto.MESSAGE, + number=17, + oneof="operation", + message=ad_group_ad_label_service.AdGroupAdLabelOperation, + ) + ad_group_ad_operation = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=ad_group_ad_service.AdGroupAdOperation, + ) + ad_group_asset_operation = proto.Field( + proto.MESSAGE, + number=56, + oneof="operation", + message=ad_group_asset_service.AdGroupAssetOperation, + ) + ad_group_bid_modifier_operation = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=ad_group_bid_modifier_service.AdGroupBidModifierOperation, + ) + ad_group_criterion_customizer_operation = proto.Field( + proto.MESSAGE, + number=77, + oneof="operation", + message=ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation, + ) + ad_group_criterion_label_operation = proto.Field( + proto.MESSAGE, + number=18, + oneof="operation", + message=ad_group_criterion_label_service.AdGroupCriterionLabelOperation, + ) + ad_group_criterion_operation = proto.Field( + proto.MESSAGE, + number=3, + oneof="operation", + message=ad_group_criterion_service.AdGroupCriterionOperation, + ) + ad_group_customizer_operation = proto.Field( + proto.MESSAGE, + number=75, + oneof="operation", + message=ad_group_customizer_service.AdGroupCustomizerOperation, + ) + ad_group_extension_setting_operation = proto.Field( + proto.MESSAGE, + number=19, + oneof="operation", + message=ad_group_extension_setting_service.AdGroupExtensionSettingOperation, + ) + ad_group_feed_operation = proto.Field( + proto.MESSAGE, + number=20, + oneof="operation", + message=ad_group_feed_service.AdGroupFeedOperation, + ) + ad_group_label_operation = proto.Field( + proto.MESSAGE, + number=21, + oneof="operation", + message=ad_group_label_service.AdGroupLabelOperation, + ) + ad_group_operation = proto.Field( + proto.MESSAGE, + number=5, + oneof="operation", + message=ad_group_service.AdGroupOperation, + ) + ad_operation = proto.Field( + proto.MESSAGE, + number=49, + oneof="operation", + message=ad_service.AdOperation, + ) + ad_parameter_operation = proto.Field( + proto.MESSAGE, + number=22, + oneof="operation", + message=ad_parameter_service.AdParameterOperation, + ) + asset_operation = proto.Field( + proto.MESSAGE, + number=23, + oneof="operation", + message=asset_service.AssetOperation, + ) + asset_group_asset_operation = proto.Field( + proto.MESSAGE, + number=65, + oneof="operation", + message=asset_group_asset_service.AssetGroupAssetOperation, + ) + asset_group_listing_group_filter_operation = proto.Field( + proto.MESSAGE, + number=78, + oneof="operation", + message=asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation, + ) + asset_group_signal_operation = proto.Field( + proto.MESSAGE, + number=80, + oneof="operation", + message=asset_group_signal_service.AssetGroupSignalOperation, + ) + asset_group_operation = proto.Field( + proto.MESSAGE, + number=62, + oneof="operation", + message=asset_group_service.AssetGroupOperation, + ) + asset_set_asset_operation = proto.Field( + proto.MESSAGE, + number=71, + oneof="operation", + message=asset_set_asset_service.AssetSetAssetOperation, + ) + asset_set_operation = proto.Field( + proto.MESSAGE, + number=72, + oneof="operation", + message=asset_set_service.AssetSetOperation, + ) + audience_operation = proto.Field( + proto.MESSAGE, + number=81, + oneof="operation", + message=audience_service.AudienceOperation, + ) + bidding_data_exclusion_operation = proto.Field( + proto.MESSAGE, + number=58, + oneof="operation", + message=bidding_data_exclusion_service.BiddingDataExclusionOperation, + ) + bidding_seasonality_adjustment_operation = proto.Field( + proto.MESSAGE, + number=59, + oneof="operation", + message=bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation, + ) + bidding_strategy_operation = proto.Field( + proto.MESSAGE, + number=6, + oneof="operation", + message=bidding_strategy_service.BiddingStrategyOperation, + ) + campaign_asset_operation = proto.Field( + proto.MESSAGE, + number=52, + oneof="operation", + message=campaign_asset_service.CampaignAssetOperation, + ) + campaign_asset_set_operation = proto.Field( + proto.MESSAGE, + number=73, + oneof="operation", + message=campaign_asset_set_service.CampaignAssetSetOperation, + ) + campaign_bid_modifier_operation = proto.Field( + proto.MESSAGE, + number=7, + oneof="operation", + message=campaign_bid_modifier_service.CampaignBidModifierOperation, + ) + campaign_budget_operation = proto.Field( + proto.MESSAGE, + number=8, + oneof="operation", + message=campaign_budget_service.CampaignBudgetOperation, + ) + campaign_conversion_goal_operation = proto.Field( + proto.MESSAGE, + number=67, + oneof="operation", + message=campaign_conversion_goal_service.CampaignConversionGoalOperation, + ) + campaign_criterion_operation = proto.Field( + proto.MESSAGE, + number=13, + oneof="operation", + message=campaign_criterion_service.CampaignCriterionOperation, + ) + campaign_customizer_operation = proto.Field( + proto.MESSAGE, + number=76, + oneof="operation", + message=campaign_customizer_service.CampaignCustomizerOperation, + ) + campaign_draft_operation = proto.Field( + proto.MESSAGE, + number=24, + oneof="operation", + message=campaign_draft_service.CampaignDraftOperation, + ) + campaign_extension_setting_operation = proto.Field( + proto.MESSAGE, + number=26, + oneof="operation", + message=campaign_extension_setting_service.CampaignExtensionSettingOperation, + ) + campaign_feed_operation = proto.Field( + proto.MESSAGE, + number=27, + oneof="operation", + message=campaign_feed_service.CampaignFeedOperation, + ) + campaign_group_operation = proto.Field( + proto.MESSAGE, + number=9, + oneof="operation", + message=campaign_group_service.CampaignGroupOperation, + ) + campaign_label_operation = proto.Field( + proto.MESSAGE, + number=28, + oneof="operation", + message=campaign_label_service.CampaignLabelOperation, + ) + campaign_operation = proto.Field( + proto.MESSAGE, + number=10, + oneof="operation", + message=campaign_service.CampaignOperation, + ) + campaign_shared_set_operation = proto.Field( + proto.MESSAGE, + number=11, + oneof="operation", + message=campaign_shared_set_service.CampaignSharedSetOperation, + ) + conversion_action_operation = proto.Field( + proto.MESSAGE, + number=12, + oneof="operation", + message=conversion_action_service.ConversionActionOperation, + ) + conversion_custom_variable_operation = proto.Field( + proto.MESSAGE, + number=55, + oneof="operation", + message=conversion_custom_variable_service.ConversionCustomVariableOperation, + ) + conversion_goal_campaign_config_operation = proto.Field( + proto.MESSAGE, + number=69, + oneof="operation", + message=conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation, + ) + conversion_value_rule_operation = proto.Field( + proto.MESSAGE, + number=63, + oneof="operation", + message=conversion_value_rule_service.ConversionValueRuleOperation, + ) + conversion_value_rule_set_operation = proto.Field( + proto.MESSAGE, + number=64, + oneof="operation", + message=conversion_value_rule_set_service.ConversionValueRuleSetOperation, + ) + custom_conversion_goal_operation = proto.Field( + proto.MESSAGE, + number=68, + oneof="operation", + message=custom_conversion_goal_service.CustomConversionGoalOperation, + ) + customer_asset_operation = proto.Field( + proto.MESSAGE, + number=57, + oneof="operation", + message=customer_asset_service.CustomerAssetOperation, + ) + customer_conversion_goal_operation = proto.Field( + proto.MESSAGE, + number=66, + oneof="operation", + message=customer_conversion_goal_service.CustomerConversionGoalOperation, + ) + customer_customizer_operation = proto.Field( + proto.MESSAGE, + number=79, + oneof="operation", + message=customer_customizer_service.CustomerCustomizerOperation, + ) + customer_extension_setting_operation = proto.Field( + proto.MESSAGE, + number=30, + oneof="operation", + message=customer_extension_setting_service.CustomerExtensionSettingOperation, + ) + customer_feed_operation = proto.Field( + proto.MESSAGE, + number=31, + oneof="operation", + message=customer_feed_service.CustomerFeedOperation, + ) + customer_label_operation = proto.Field( + proto.MESSAGE, + number=32, + oneof="operation", + message=customer_label_service.CustomerLabelOperation, + ) + customer_negative_criterion_operation = proto.Field( + proto.MESSAGE, + number=34, + oneof="operation", + message=customer_negative_criterion_service.CustomerNegativeCriterionOperation, + ) + customer_operation = proto.Field( + proto.MESSAGE, + number=35, + oneof="operation", + message=customer_service.CustomerOperation, + ) + customizer_attribute_operation = proto.Field( + proto.MESSAGE, + number=70, + oneof="operation", + message=customizer_attribute_service.CustomizerAttributeOperation, + ) + experiment_operation = proto.Field( + proto.MESSAGE, + number=82, + oneof="operation", + message=experiment_service.ExperimentOperation, + ) + experiment_arm_operation = proto.Field( + proto.MESSAGE, + number=83, + oneof="operation", + message=experiment_arm_service.ExperimentArmOperation, + ) + extension_feed_item_operation = proto.Field( + proto.MESSAGE, + number=36, + oneof="operation", + message=extension_feed_item_service.ExtensionFeedItemOperation, + ) + feed_item_operation = proto.Field( + proto.MESSAGE, + number=37, + oneof="operation", + message=feed_item_service.FeedItemOperation, + ) + feed_item_set_operation = proto.Field( + proto.MESSAGE, + number=53, + oneof="operation", + message=feed_item_set_service.FeedItemSetOperation, + ) + feed_item_set_link_operation = proto.Field( + proto.MESSAGE, + number=54, + oneof="operation", + message=feed_item_set_link_service.FeedItemSetLinkOperation, + ) + feed_item_target_operation = proto.Field( + proto.MESSAGE, + number=38, + oneof="operation", + message=feed_item_target_service.FeedItemTargetOperation, + ) + feed_mapping_operation = proto.Field( + proto.MESSAGE, + number=39, + oneof="operation", + message=feed_mapping_service.FeedMappingOperation, + ) + feed_operation = proto.Field( + proto.MESSAGE, + number=40, + oneof="operation", + message=feed_service.FeedOperation, + ) + keyword_plan_ad_group_operation = proto.Field( + proto.MESSAGE, + number=44, + oneof="operation", + message=keyword_plan_ad_group_service.KeywordPlanAdGroupOperation, + ) + keyword_plan_ad_group_keyword_operation = proto.Field( + proto.MESSAGE, + number=50, + oneof="operation", + message=keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation, + ) + keyword_plan_campaign_keyword_operation = proto.Field( + proto.MESSAGE, + number=51, + oneof="operation", + message=keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation, + ) + keyword_plan_campaign_operation = proto.Field( + proto.MESSAGE, + number=45, + oneof="operation", + message=keyword_plan_campaign_service.KeywordPlanCampaignOperation, + ) + keyword_plan_operation = proto.Field( + proto.MESSAGE, + number=48, + oneof="operation", + message=keyword_plan_service.KeywordPlanOperation, + ) + label_operation = proto.Field( + proto.MESSAGE, + number=41, + oneof="operation", + message=label_service.LabelOperation, + ) + media_file_operation = proto.Field( + proto.MESSAGE, + number=42, + oneof="operation", + message=media_file_service.MediaFileOperation, + ) + remarketing_action_operation = proto.Field( + proto.MESSAGE, + number=43, + oneof="operation", + message=remarketing_action_service.RemarketingActionOperation, + ) + shared_criterion_operation = proto.Field( + proto.MESSAGE, + number=14, + oneof="operation", + message=shared_criterion_service.SharedCriterionOperation, + ) + shared_set_operation = proto.Field( + proto.MESSAGE, + number=15, + oneof="operation", + message=shared_set_service.SharedSetOperation, + ) + smart_campaign_setting_operation = proto.Field( + proto.MESSAGE, + number=61, + oneof="operation", + message=smart_campaign_setting_service.SmartCampaignSettingOperation, + ) + user_list_operation = proto.Field( + proto.MESSAGE, + number=16, + oneof="operation", + message=user_list_service.UserListOperation, + ) + + +class MutateOperationResponse(proto.Message): + r"""Response message for the resource mutate. + + 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: + ad_group_ad_label_result (google.ads.googleads.v12.services.types.MutateAdGroupAdLabelResult): + The result for the ad group ad label mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_ad_result (google.ads.googleads.v12.services.types.MutateAdGroupAdResult): + The result for the ad group ad mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_asset_result (google.ads.googleads.v12.services.types.MutateAdGroupAssetResult): + The result for the ad group asset mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_bid_modifier_result (google.ads.googleads.v12.services.types.MutateAdGroupBidModifierResult): + The result for the ad group bid modifier + mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_criterion_customizer_result (google.ads.googleads.v12.services.types.MutateAdGroupCriterionCustomizerResult): + The result for the ad group criterion + customizer mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_criterion_label_result (google.ads.googleads.v12.services.types.MutateAdGroupCriterionLabelResult): + The result for the ad group criterion label + mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_criterion_result (google.ads.googleads.v12.services.types.MutateAdGroupCriterionResult): + The result for the ad group criterion mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_customizer_result (google.ads.googleads.v12.services.types.MutateAdGroupCustomizerResult): + The result for the ad group customizer + mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_extension_setting_result (google.ads.googleads.v12.services.types.MutateAdGroupExtensionSettingResult): + The result for the ad group extension setting + mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_feed_result (google.ads.googleads.v12.services.types.MutateAdGroupFeedResult): + The result for the ad group feed mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_label_result (google.ads.googleads.v12.services.types.MutateAdGroupLabelResult): + The result for the ad group label mutate. + + This field is a member of `oneof`_ ``response``. + ad_group_result (google.ads.googleads.v12.services.types.MutateAdGroupResult): + The result for the ad group mutate. + + This field is a member of `oneof`_ ``response``. + ad_parameter_result (google.ads.googleads.v12.services.types.MutateAdParameterResult): + The result for the ad parameter mutate. + + This field is a member of `oneof`_ ``response``. + ad_result (google.ads.googleads.v12.services.types.MutateAdResult): + The result for the ad mutate. + + This field is a member of `oneof`_ ``response``. + asset_result (google.ads.googleads.v12.services.types.MutateAssetResult): + The result for the asset mutate. + + This field is a member of `oneof`_ ``response``. + asset_group_asset_result (google.ads.googleads.v12.services.types.MutateAssetGroupAssetResult): + The result for the asset group asset mutate. + + This field is a member of `oneof`_ ``response``. + asset_group_listing_group_filter_result (google.ads.googleads.v12.services.types.MutateAssetGroupListingGroupFilterResult): + The result for the asset group listing group + filter mutate. + + This field is a member of `oneof`_ ``response``. + asset_group_signal_result (google.ads.googleads.v12.services.types.MutateAssetGroupSignalResult): + The result for the asset group signal mutate. + + This field is a member of `oneof`_ ``response``. + asset_group_result (google.ads.googleads.v12.services.types.MutateAssetGroupResult): + The result for the asset group mutate. + + This field is a member of `oneof`_ ``response``. + asset_set_asset_result (google.ads.googleads.v12.services.types.MutateAssetSetAssetResult): + The result for the asset set asset mutate. + + This field is a member of `oneof`_ ``response``. + asset_set_result (google.ads.googleads.v12.services.types.MutateAssetSetResult): + The result for the asset set mutate. + + This field is a member of `oneof`_ ``response``. + audience_result (google.ads.googleads.v12.services.types.MutateAudienceResult): + The result for the audience mutate. + + This field is a member of `oneof`_ ``response``. + bidding_data_exclusion_result (google.ads.googleads.v12.services.types.MutateBiddingDataExclusionsResult): + The result for the bidding data exclusion + mutate. + + This field is a member of `oneof`_ ``response``. + bidding_seasonality_adjustment_result (google.ads.googleads.v12.services.types.MutateBiddingSeasonalityAdjustmentsResult): + The result for the bidding seasonality + adjustment mutate. + + This field is a member of `oneof`_ ``response``. + bidding_strategy_result (google.ads.googleads.v12.services.types.MutateBiddingStrategyResult): + The result for the bidding strategy mutate. + + This field is a member of `oneof`_ ``response``. + campaign_asset_result (google.ads.googleads.v12.services.types.MutateCampaignAssetResult): + The result for the campaign asset mutate. + + This field is a member of `oneof`_ ``response``. + campaign_asset_set_result (google.ads.googleads.v12.services.types.MutateCampaignAssetSetResult): + The result for the campaign asset set mutate. + + This field is a member of `oneof`_ ``response``. + campaign_bid_modifier_result (google.ads.googleads.v12.services.types.MutateCampaignBidModifierResult): + The result for the campaign bid modifier + mutate. + + This field is a member of `oneof`_ ``response``. + campaign_budget_result (google.ads.googleads.v12.services.types.MutateCampaignBudgetResult): + The result for the campaign budget mutate. + + This field is a member of `oneof`_ ``response``. + campaign_conversion_goal_result (google.ads.googleads.v12.services.types.MutateCampaignConversionGoalResult): + The result for the campaign conversion goal + mutate. + + This field is a member of `oneof`_ ``response``. + campaign_criterion_result (google.ads.googleads.v12.services.types.MutateCampaignCriterionResult): + The result for the campaign criterion mutate. + + This field is a member of `oneof`_ ``response``. + campaign_customizer_result (google.ads.googleads.v12.services.types.MutateCampaignCustomizerResult): + The result for the campaign customizer + mutate. + + This field is a member of `oneof`_ ``response``. + campaign_draft_result (google.ads.googleads.v12.services.types.MutateCampaignDraftResult): + The result for the campaign draft mutate. + + This field is a member of `oneof`_ ``response``. + campaign_extension_setting_result (google.ads.googleads.v12.services.types.MutateCampaignExtensionSettingResult): + The result for the campaign extension setting + mutate. + + This field is a member of `oneof`_ ``response``. + campaign_feed_result (google.ads.googleads.v12.services.types.MutateCampaignFeedResult): + The result for the campaign feed mutate. + + This field is a member of `oneof`_ ``response``. + campaign_group_result (google.ads.googleads.v12.services.types.MutateCampaignGroupResult): + The result for the campaign group mutate. + + This field is a member of `oneof`_ ``response``. + campaign_label_result (google.ads.googleads.v12.services.types.MutateCampaignLabelResult): + The result for the campaign label mutate. + + This field is a member of `oneof`_ ``response``. + campaign_result (google.ads.googleads.v12.services.types.MutateCampaignResult): + The result for the campaign mutate. + + This field is a member of `oneof`_ ``response``. + campaign_shared_set_result (google.ads.googleads.v12.services.types.MutateCampaignSharedSetResult): + The result for the campaign shared set + mutate. + + This field is a member of `oneof`_ ``response``. + conversion_action_result (google.ads.googleads.v12.services.types.MutateConversionActionResult): + The result for the conversion action mutate. + + This field is a member of `oneof`_ ``response``. + conversion_custom_variable_result (google.ads.googleads.v12.services.types.MutateConversionCustomVariableResult): + The result for the conversion custom variable + mutate. + + This field is a member of `oneof`_ ``response``. + conversion_goal_campaign_config_result (google.ads.googleads.v12.services.types.MutateConversionGoalCampaignConfigResult): + The result for the conversion goal campaign + config mutate. + + This field is a member of `oneof`_ ``response``. + conversion_value_rule_result (google.ads.googleads.v12.services.types.MutateConversionValueRuleResult): + The result for the conversion value rule + mutate. + + This field is a member of `oneof`_ ``response``. + conversion_value_rule_set_result (google.ads.googleads.v12.services.types.MutateConversionValueRuleSetResult): + The result for the conversion value rule set + mutate. + + This field is a member of `oneof`_ ``response``. + custom_conversion_goal_result (google.ads.googleads.v12.services.types.MutateCustomConversionGoalResult): + The result for the custom conversion goal + mutate. + + This field is a member of `oneof`_ ``response``. + customer_asset_result (google.ads.googleads.v12.services.types.MutateCustomerAssetResult): + The result for the customer asset mutate. + + This field is a member of `oneof`_ ``response``. + customer_conversion_goal_result (google.ads.googleads.v12.services.types.MutateCustomerConversionGoalResult): + The result for the customer conversion goal + mutate. + + This field is a member of `oneof`_ ``response``. + customer_customizer_result (google.ads.googleads.v12.services.types.MutateCustomerCustomizerResult): + The result for the customer customizer + mutate. + + This field is a member of `oneof`_ ``response``. + customer_extension_setting_result (google.ads.googleads.v12.services.types.MutateCustomerExtensionSettingResult): + The result for the customer extension setting + mutate. + + This field is a member of `oneof`_ ``response``. + customer_feed_result (google.ads.googleads.v12.services.types.MutateCustomerFeedResult): + The result for the customer feed mutate. + + This field is a member of `oneof`_ ``response``. + customer_label_result (google.ads.googleads.v12.services.types.MutateCustomerLabelResult): + The result for the customer label mutate. + + This field is a member of `oneof`_ ``response``. + customer_negative_criterion_result (google.ads.googleads.v12.services.types.MutateCustomerNegativeCriteriaResult): + The result for the customer negative + criterion mutate. + + This field is a member of `oneof`_ ``response``. + customer_result (google.ads.googleads.v12.services.types.MutateCustomerResult): + The result for the customer mutate. + + This field is a member of `oneof`_ ``response``. + customizer_attribute_result (google.ads.googleads.v12.services.types.MutateCustomizerAttributeResult): + The result for the customizer attribute + mutate. + + This field is a member of `oneof`_ ``response``. + experiment_result (google.ads.googleads.v12.services.types.MutateExperimentResult): + The result for the experiment mutate. + + This field is a member of `oneof`_ ``response``. + experiment_arm_result (google.ads.googleads.v12.services.types.MutateExperimentArmResult): + The result for the experiment arm mutate. + + This field is a member of `oneof`_ ``response``. + extension_feed_item_result (google.ads.googleads.v12.services.types.MutateExtensionFeedItemResult): + The result for the extension feed item + mutate. + + This field is a member of `oneof`_ ``response``. + feed_item_result (google.ads.googleads.v12.services.types.MutateFeedItemResult): + The result for the feed item mutate. + + This field is a member of `oneof`_ ``response``. + feed_item_set_result (google.ads.googleads.v12.services.types.MutateFeedItemSetResult): + The result for the feed item set mutate. + + This field is a member of `oneof`_ ``response``. + feed_item_set_link_result (google.ads.googleads.v12.services.types.MutateFeedItemSetLinkResult): + The result for the feed item set link mutate. + + This field is a member of `oneof`_ ``response``. + feed_item_target_result (google.ads.googleads.v12.services.types.MutateFeedItemTargetResult): + The result for the feed item target mutate. + + This field is a member of `oneof`_ ``response``. + feed_mapping_result (google.ads.googleads.v12.services.types.MutateFeedMappingResult): + The result for the feed mapping mutate. + + This field is a member of `oneof`_ ``response``. + feed_result (google.ads.googleads.v12.services.types.MutateFeedResult): + The result for the feed mutate. + + This field is a member of `oneof`_ ``response``. + keyword_plan_ad_group_result (google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupResult): + The result for the keyword plan ad group + mutate. + + This field is a member of `oneof`_ ``response``. + keyword_plan_campaign_result (google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignResult): + The result for the keyword plan campaign + mutate. + + This field is a member of `oneof`_ ``response``. + keyword_plan_ad_group_keyword_result (google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupKeywordResult): + The result for the keyword plan ad group + keyword mutate. + + This field is a member of `oneof`_ ``response``. + keyword_plan_campaign_keyword_result (google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignKeywordResult): + The result for the keyword plan campaign + keyword mutate. + + This field is a member of `oneof`_ ``response``. + keyword_plan_result (google.ads.googleads.v12.services.types.MutateKeywordPlansResult): + The result for the keyword plan mutate. + + This field is a member of `oneof`_ ``response``. + label_result (google.ads.googleads.v12.services.types.MutateLabelResult): + The result for the label mutate. + + This field is a member of `oneof`_ ``response``. + media_file_result (google.ads.googleads.v12.services.types.MutateMediaFileResult): + The result for the media file mutate. + + This field is a member of `oneof`_ ``response``. + remarketing_action_result (google.ads.googleads.v12.services.types.MutateRemarketingActionResult): + The result for the remarketing action mutate. + + This field is a member of `oneof`_ ``response``. + shared_criterion_result (google.ads.googleads.v12.services.types.MutateSharedCriterionResult): + The result for the shared criterion mutate. + + This field is a member of `oneof`_ ``response``. + shared_set_result (google.ads.googleads.v12.services.types.MutateSharedSetResult): + The result for the shared set mutate. + + This field is a member of `oneof`_ ``response``. + smart_campaign_setting_result (google.ads.googleads.v12.services.types.MutateSmartCampaignSettingResult): + The result for the Smart campaign setting + mutate. + + This field is a member of `oneof`_ ``response``. + user_list_result (google.ads.googleads.v12.services.types.MutateUserListResult): + The result for the user list mutate. + + This field is a member of `oneof`_ ``response``. + """ + + ad_group_ad_label_result = proto.Field( + proto.MESSAGE, + number=17, + oneof="response", + message=ad_group_ad_label_service.MutateAdGroupAdLabelResult, + ) + ad_group_ad_result = proto.Field( + proto.MESSAGE, + number=1, + oneof="response", + message=ad_group_ad_service.MutateAdGroupAdResult, + ) + ad_group_asset_result = proto.Field( + proto.MESSAGE, + number=56, + oneof="response", + message=ad_group_asset_service.MutateAdGroupAssetResult, + ) + ad_group_bid_modifier_result = proto.Field( + proto.MESSAGE, + number=2, + oneof="response", + message=ad_group_bid_modifier_service.MutateAdGroupBidModifierResult, + ) + ad_group_criterion_customizer_result = proto.Field( + proto.MESSAGE, + number=77, + oneof="response", + message=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizerResult, + ) + ad_group_criterion_label_result = proto.Field( + proto.MESSAGE, + number=18, + oneof="response", + message=ad_group_criterion_label_service.MutateAdGroupCriterionLabelResult, + ) + ad_group_criterion_result = proto.Field( + proto.MESSAGE, + number=3, + oneof="response", + message=ad_group_criterion_service.MutateAdGroupCriterionResult, + ) + ad_group_customizer_result = proto.Field( + proto.MESSAGE, + number=75, + oneof="response", + message=ad_group_customizer_service.MutateAdGroupCustomizerResult, + ) + ad_group_extension_setting_result = proto.Field( + proto.MESSAGE, + number=19, + oneof="response", + message=ad_group_extension_setting_service.MutateAdGroupExtensionSettingResult, + ) + ad_group_feed_result = proto.Field( + proto.MESSAGE, + number=20, + oneof="response", + message=ad_group_feed_service.MutateAdGroupFeedResult, + ) + ad_group_label_result = proto.Field( + proto.MESSAGE, + number=21, + oneof="response", + message=ad_group_label_service.MutateAdGroupLabelResult, + ) + ad_group_result = proto.Field( + proto.MESSAGE, + number=5, + oneof="response", + message=ad_group_service.MutateAdGroupResult, + ) + ad_parameter_result = proto.Field( + proto.MESSAGE, + number=22, + oneof="response", + message=ad_parameter_service.MutateAdParameterResult, + ) + ad_result = proto.Field( + proto.MESSAGE, + number=49, + oneof="response", + message=ad_service.MutateAdResult, + ) + asset_result = proto.Field( + proto.MESSAGE, + number=23, + oneof="response", + message=asset_service.MutateAssetResult, + ) + asset_group_asset_result = proto.Field( + proto.MESSAGE, + number=65, + oneof="response", + message=asset_group_asset_service.MutateAssetGroupAssetResult, + ) + asset_group_listing_group_filter_result = proto.Field( + proto.MESSAGE, + number=78, + oneof="response", + message=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFilterResult, + ) + asset_group_signal_result = proto.Field( + proto.MESSAGE, + number=79, + oneof="response", + message=asset_group_signal_service.MutateAssetGroupSignalResult, + ) + asset_group_result = proto.Field( + proto.MESSAGE, + number=62, + oneof="response", + message=asset_group_service.MutateAssetGroupResult, + ) + asset_set_asset_result = proto.Field( + proto.MESSAGE, + number=71, + oneof="response", + message=asset_set_asset_service.MutateAssetSetAssetResult, + ) + asset_set_result = proto.Field( + proto.MESSAGE, + number=72, + oneof="response", + message=asset_set_service.MutateAssetSetResult, + ) + audience_result = proto.Field( + proto.MESSAGE, + number=80, + oneof="response", + message=audience_service.MutateAudienceResult, + ) + bidding_data_exclusion_result = proto.Field( + proto.MESSAGE, + number=58, + oneof="response", + message=bidding_data_exclusion_service.MutateBiddingDataExclusionsResult, + ) + bidding_seasonality_adjustment_result = proto.Field( + proto.MESSAGE, + number=59, + oneof="response", + message=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResult, + ) + bidding_strategy_result = proto.Field( + proto.MESSAGE, + number=6, + oneof="response", + message=bidding_strategy_service.MutateBiddingStrategyResult, + ) + campaign_asset_result = proto.Field( + proto.MESSAGE, + number=52, + oneof="response", + message=campaign_asset_service.MutateCampaignAssetResult, + ) + campaign_asset_set_result = proto.Field( + proto.MESSAGE, + number=73, + oneof="response", + message=campaign_asset_set_service.MutateCampaignAssetSetResult, + ) + campaign_bid_modifier_result = proto.Field( + proto.MESSAGE, + number=7, + oneof="response", + message=campaign_bid_modifier_service.MutateCampaignBidModifierResult, + ) + campaign_budget_result = proto.Field( + proto.MESSAGE, + number=8, + oneof="response", + message=campaign_budget_service.MutateCampaignBudgetResult, + ) + campaign_conversion_goal_result = proto.Field( + proto.MESSAGE, + number=67, + oneof="response", + message=campaign_conversion_goal_service.MutateCampaignConversionGoalResult, + ) + campaign_criterion_result = proto.Field( + proto.MESSAGE, + number=13, + oneof="response", + message=campaign_criterion_service.MutateCampaignCriterionResult, + ) + campaign_customizer_result = proto.Field( + proto.MESSAGE, + number=76, + oneof="response", + message=campaign_customizer_service.MutateCampaignCustomizerResult, + ) + campaign_draft_result = proto.Field( + proto.MESSAGE, + number=24, + oneof="response", + message=campaign_draft_service.MutateCampaignDraftResult, + ) + campaign_extension_setting_result = proto.Field( + proto.MESSAGE, + number=26, + oneof="response", + message=campaign_extension_setting_service.MutateCampaignExtensionSettingResult, + ) + campaign_feed_result = proto.Field( + proto.MESSAGE, + number=27, + oneof="response", + message=campaign_feed_service.MutateCampaignFeedResult, + ) + campaign_group_result = proto.Field( + proto.MESSAGE, + number=9, + oneof="response", + message=campaign_group_service.MutateCampaignGroupResult, + ) + campaign_label_result = proto.Field( + proto.MESSAGE, + number=28, + oneof="response", + message=campaign_label_service.MutateCampaignLabelResult, + ) + campaign_result = proto.Field( + proto.MESSAGE, + number=10, + oneof="response", + message=campaign_service.MutateCampaignResult, + ) + campaign_shared_set_result = proto.Field( + proto.MESSAGE, + number=11, + oneof="response", + message=campaign_shared_set_service.MutateCampaignSharedSetResult, + ) + conversion_action_result = proto.Field( + proto.MESSAGE, + number=12, + oneof="response", + message=conversion_action_service.MutateConversionActionResult, + ) + conversion_custom_variable_result = proto.Field( + proto.MESSAGE, + number=55, + oneof="response", + message=conversion_custom_variable_service.MutateConversionCustomVariableResult, + ) + conversion_goal_campaign_config_result = proto.Field( + proto.MESSAGE, + number=69, + oneof="response", + message=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigResult, + ) + conversion_value_rule_result = proto.Field( + proto.MESSAGE, + number=63, + oneof="response", + message=conversion_value_rule_service.MutateConversionValueRuleResult, + ) + conversion_value_rule_set_result = proto.Field( + proto.MESSAGE, + number=64, + oneof="response", + message=conversion_value_rule_set_service.MutateConversionValueRuleSetResult, + ) + custom_conversion_goal_result = proto.Field( + proto.MESSAGE, + number=68, + oneof="response", + message=custom_conversion_goal_service.MutateCustomConversionGoalResult, + ) + customer_asset_result = proto.Field( + proto.MESSAGE, + number=57, + oneof="response", + message=customer_asset_service.MutateCustomerAssetResult, + ) + customer_conversion_goal_result = proto.Field( + proto.MESSAGE, + number=66, + oneof="response", + message=customer_conversion_goal_service.MutateCustomerConversionGoalResult, + ) + customer_customizer_result = proto.Field( + proto.MESSAGE, + number=74, + oneof="response", + message=customer_customizer_service.MutateCustomerCustomizerResult, + ) + customer_extension_setting_result = proto.Field( + proto.MESSAGE, + number=30, + oneof="response", + message=customer_extension_setting_service.MutateCustomerExtensionSettingResult, + ) + customer_feed_result = proto.Field( + proto.MESSAGE, + number=31, + oneof="response", + message=customer_feed_service.MutateCustomerFeedResult, + ) + customer_label_result = proto.Field( + proto.MESSAGE, + number=32, + oneof="response", + message=customer_label_service.MutateCustomerLabelResult, + ) + customer_negative_criterion_result = proto.Field( + proto.MESSAGE, + number=34, + oneof="response", + message=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResult, + ) + customer_result = proto.Field( + proto.MESSAGE, + number=35, + oneof="response", + message=customer_service.MutateCustomerResult, + ) + customizer_attribute_result = proto.Field( + proto.MESSAGE, + number=70, + oneof="response", + message=customizer_attribute_service.MutateCustomizerAttributeResult, + ) + experiment_result = proto.Field( + proto.MESSAGE, + number=81, + oneof="response", + message=experiment_service.MutateExperimentResult, + ) + experiment_arm_result = proto.Field( + proto.MESSAGE, + number=82, + oneof="response", + message=experiment_arm_service.MutateExperimentArmResult, + ) + extension_feed_item_result = proto.Field( + proto.MESSAGE, + number=36, + oneof="response", + message=extension_feed_item_service.MutateExtensionFeedItemResult, + ) + feed_item_result = proto.Field( + proto.MESSAGE, + number=37, + oneof="response", + message=feed_item_service.MutateFeedItemResult, + ) + feed_item_set_result = proto.Field( + proto.MESSAGE, + number=53, + oneof="response", + message=feed_item_set_service.MutateFeedItemSetResult, + ) + feed_item_set_link_result = proto.Field( + proto.MESSAGE, + number=54, + oneof="response", + message=feed_item_set_link_service.MutateFeedItemSetLinkResult, + ) + feed_item_target_result = proto.Field( + proto.MESSAGE, + number=38, + oneof="response", + message=feed_item_target_service.MutateFeedItemTargetResult, + ) + feed_mapping_result = proto.Field( + proto.MESSAGE, + number=39, + oneof="response", + message=feed_mapping_service.MutateFeedMappingResult, + ) + feed_result = proto.Field( + proto.MESSAGE, + number=40, + oneof="response", + message=feed_service.MutateFeedResult, + ) + keyword_plan_ad_group_result = proto.Field( + proto.MESSAGE, + number=44, + oneof="response", + message=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupResult, + ) + keyword_plan_campaign_result = proto.Field( + proto.MESSAGE, + number=45, + oneof="response", + message=keyword_plan_campaign_service.MutateKeywordPlanCampaignResult, + ) + keyword_plan_ad_group_keyword_result = proto.Field( + proto.MESSAGE, + number=50, + oneof="response", + message=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordResult, + ) + keyword_plan_campaign_keyword_result = proto.Field( + proto.MESSAGE, + number=51, + oneof="response", + message=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordResult, + ) + keyword_plan_result = proto.Field( + proto.MESSAGE, + number=48, + oneof="response", + message=keyword_plan_service.MutateKeywordPlansResult, + ) + label_result = proto.Field( + proto.MESSAGE, + number=41, + oneof="response", + message=label_service.MutateLabelResult, + ) + media_file_result = proto.Field( + proto.MESSAGE, + number=42, + oneof="response", + message=media_file_service.MutateMediaFileResult, + ) + remarketing_action_result = proto.Field( + proto.MESSAGE, + number=43, + oneof="response", + message=remarketing_action_service.MutateRemarketingActionResult, + ) + shared_criterion_result = proto.Field( + proto.MESSAGE, + number=14, + oneof="response", + message=shared_criterion_service.MutateSharedCriterionResult, + ) + shared_set_result = proto.Field( + proto.MESSAGE, + number=15, + oneof="response", + message=shared_set_service.MutateSharedSetResult, + ) + smart_campaign_setting_result = proto.Field( + proto.MESSAGE, + number=61, + oneof="response", + message=smart_campaign_setting_service.MutateSmartCampaignSettingResult, + ) + user_list_result = proto.Field( + proto.MESSAGE, + number=16, + oneof="response", + message=user_list_service.MutateUserListResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/invoice_service.py b/google/ads/googleads/v12/services/types/invoice_service.py new file mode 100644 index 000000000..68b776424 --- /dev/null +++ b/google/ads/googleads/v12/services/types/invoice_service.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import month_of_year +from google.ads.googleads.v12.resources.types import invoice + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={"ListInvoicesRequest", "ListInvoicesResponse",}, +) + + +class ListInvoicesRequest(proto.Message): + r"""Request message for fetching the invoices of a given billing + setup that were issued during a given month. + + Attributes: + customer_id (str): + Required. The ID of the customer to fetch + invoices for. + billing_setup (str): + Required. The billing setup resource name of the requested + invoices. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + issue_year (str): + Required. The issue year to retrieve + invoices, in yyyy format. Only invoices issued + in 2019 or later can be retrieved. + issue_month (google.ads.googleads.v12.enums.types.MonthOfYearEnum.MonthOfYear): + Required. The issue month to retrieve + invoices. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + billing_setup = proto.Field(proto.STRING, number=2,) + issue_year = proto.Field(proto.STRING, number=3,) + issue_month = proto.Field( + proto.ENUM, number=4, enum=month_of_year.MonthOfYearEnum.MonthOfYear, + ) + + +class ListInvoicesResponse(proto.Message): + r"""Response message for + [InvoiceService.ListInvoices][google.ads.googleads.v12.services.InvoiceService.ListInvoices]. + + Attributes: + invoices (Sequence[google.ads.googleads.v12.resources.types.Invoice]): + The list of invoices that match the billing + setup and time period. + """ + + invoices = proto.RepeatedField( + proto.MESSAGE, number=1, message=invoice.Invoice, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_ad_group_keyword_service.py b/google/ads/googleads/v12/services/types/keyword_plan_ad_group_keyword_service.py new file mode 100644 index 000000000..2a96ef589 --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_ad_group_keyword_service.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + keyword_plan_ad_group_keyword, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateKeywordPlanAdGroupKeywordsRequest", + "KeywordPlanAdGroupKeywordOperation", + "MutateKeywordPlanAdGroupKeywordsResponse", + "MutateKeywordPlanAdGroupKeywordResult", + }, +) + + +class MutateKeywordPlanAdGroupKeywordsRequest(proto.Message): + r"""Request message for + [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v12.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + Keyword Plan ad group keywords are being + modified. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanAdGroupKeywordOperation]): + Required. The list of operations to perform + on individual Keyword Plan ad group keywords. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanAdGroupKeywordOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class KeywordPlanAdGroupKeywordOperation(proto.Message): + r"""A single operation (create, update, remove) on a Keyword Plan + ad group keyword. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.KeywordPlanAdGroupKeyword): + Create operation: No resource name is + expected for the new Keyword Plan ad group + keyword. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.KeywordPlanAdGroupKeyword): + Update operation: The Keyword Plan ad group + keyword is expected to have a valid resource + name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed Keyword + Plan ad group keyword is expected, in this format: + + ``customers/{customer_id}/keywordPlanAdGroupKeywords/{kp_ad_group_keyword_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=keyword_plan_ad_group_keyword.KeywordPlanAdGroupKeyword, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=keyword_plan_ad_group_keyword.KeywordPlanAdGroupKeyword, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateKeywordPlanAdGroupKeywordsResponse(proto.Message): + r"""Response message for a Keyword Plan ad group keyword mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupKeywordResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MutateKeywordPlanAdGroupKeywordResult", + ) + + +class MutateKeywordPlanAdGroupKeywordResult(proto.Message): + r"""The result for the Keyword Plan ad group keyword mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_ad_group_service.py b/google/ads/googleads/v12/services/types/keyword_plan_ad_group_service.py new file mode 100644 index 000000000..88fd6e3c4 --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_ad_group_service.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import keyword_plan_ad_group +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateKeywordPlanAdGroupsRequest", + "KeywordPlanAdGroupOperation", + "MutateKeywordPlanAdGroupsResponse", + "MutateKeywordPlanAdGroupResult", + }, +) + + +class MutateKeywordPlanAdGroupsRequest(proto.Message): + r"""Request message for + [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v12.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + Keyword Plan ad groups are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanAdGroupOperation]): + Required. The list of operations to perform + on individual Keyword Plan ad groups. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanAdGroupOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class KeywordPlanAdGroupOperation(proto.Message): + r"""A single operation (create, update, remove) on a Keyword Plan + ad group. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.KeywordPlanAdGroup): + Create operation: No resource name is + expected for the new Keyword Plan ad group. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.KeywordPlanAdGroup): + Update operation: The Keyword Plan ad group + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed Keyword + Plan ad group is expected, in this format: + + ``customers/{customer_id}/keywordPlanAdGroups/{kp_ad_group_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=keyword_plan_ad_group.KeywordPlanAdGroup, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=keyword_plan_ad_group.KeywordPlanAdGroup, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateKeywordPlanAdGroupsResponse(proto.Message): + r"""Response message for a Keyword Plan ad group mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateKeywordPlanAdGroupResult]): + All results for the mutate. The order of the + results is determined by the order of the + keywords in the original request. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateKeywordPlanAdGroupResult", + ) + + +class MutateKeywordPlanAdGroupResult(proto.Message): + r"""The result for the Keyword Plan ad group mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_campaign_keyword_service.py b/google/ads/googleads/v12/services/types/keyword_plan_campaign_keyword_service.py new file mode 100644 index 000000000..3a2b5b0aa --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_campaign_keyword_service.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import ( + keyword_plan_campaign_keyword, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateKeywordPlanCampaignKeywordsRequest", + "KeywordPlanCampaignKeywordOperation", + "MutateKeywordPlanCampaignKeywordsResponse", + "MutateKeywordPlanCampaignKeywordResult", + }, +) + + +class MutateKeywordPlanCampaignKeywordsRequest(proto.Message): + r"""Request message for + [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v12.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign keywords are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignKeywordOperation]): + Required. The list of operations to perform + on individual Keyword Plan campaign keywords. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanCampaignKeywordOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class KeywordPlanCampaignKeywordOperation(proto.Message): + r"""A single operation (create, update, remove) on a Keyword Plan + campaign keyword. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.KeywordPlanCampaignKeyword): + Create operation: No resource name is + expected for the new Keyword Plan campaign + keyword. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.KeywordPlanCampaignKeyword): + Update operation: The Keyword Plan campaign + keyword expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed Keyword + Plan campaign keywords expected in this format: + + ``customers/{customer_id}/keywordPlanCampaignKeywords/{kp_campaign_keyword_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=keyword_plan_campaign_keyword.KeywordPlanCampaignKeyword, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=keyword_plan_campaign_keyword.KeywordPlanCampaignKeyword, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateKeywordPlanCampaignKeywordsResponse(proto.Message): + r"""Response message for a Keyword Plan campaign keyword mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignKeywordResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MutateKeywordPlanCampaignKeywordResult", + ) + + +class MutateKeywordPlanCampaignKeywordResult(proto.Message): + r"""The result for the Keyword Plan campaign keyword mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_campaign_service.py b/google/ads/googleads/v12/services/types/keyword_plan_campaign_service.py new file mode 100644 index 000000000..842dfb365 --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_campaign_service.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import keyword_plan_campaign +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateKeywordPlanCampaignsRequest", + "KeywordPlanCampaignOperation", + "MutateKeywordPlanCampaignsResponse", + "MutateKeywordPlanCampaignResult", + }, +) + + +class MutateKeywordPlanCampaignsRequest(proto.Message): + r"""Request message for + [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v12.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + Keyword Plan campaigns are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignOperation]): + Required. The list of operations to perform + on individual Keyword Plan campaigns. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanCampaignOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class KeywordPlanCampaignOperation(proto.Message): + r"""A single operation (create, update, remove) on a Keyword Plan + campaign. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.KeywordPlanCampaign): + Create operation: No resource name is + expected for the new Keyword Plan campaign. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.KeywordPlanCampaign): + Update operation: The Keyword Plan campaign + is expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed Keyword + Plan campaign is expected, in this format: + + ``customers/{customer_id}/keywordPlanCampaigns/{keywordPlan_campaign_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=keyword_plan_campaign.KeywordPlanCampaign, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=keyword_plan_campaign.KeywordPlanCampaign, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateKeywordPlanCampaignsResponse(proto.Message): + r"""Response message for a Keyword Plan campaign mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateKeywordPlanCampaignResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateKeywordPlanCampaignResult", + ) + + +class MutateKeywordPlanCampaignResult(proto.Message): + r"""The result for the Keyword Plan campaign mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_idea_service.py b/google/ads/googleads/v12/services/types/keyword_plan_idea_service.py new file mode 100644 index 000000000..8518bd090 --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_idea_service.py @@ -0,0 +1,508 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import keyword_plan_common +from google.ads.googleads.v12.enums.types import keyword_match_type +from google.ads.googleads.v12.enums.types import keyword_plan_keyword_annotation +from google.ads.googleads.v12.enums.types import ( + keyword_plan_network as gage_keyword_plan_network, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "GenerateKeywordIdeasRequest", + "KeywordAndUrlSeed", + "KeywordSeed", + "SiteSeed", + "UrlSeed", + "GenerateKeywordIdeaResponse", + "GenerateKeywordIdeaResult", + "GenerateKeywordHistoricalMetricsRequest", + "GenerateKeywordHistoricalMetricsResponse", + "GenerateKeywordHistoricalMetricsResult", + "GenerateAdGroupThemesRequest", + "GenerateAdGroupThemesResponse", + "AdGroupKeywordSuggestion", + "UnusableAdGroup", + }, +) + + +class GenerateKeywordIdeasRequest(proto.Message): + r"""Request message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + The ID of the customer with the + recommendation. + language (str): + The resource name of the language to target. + Each keyword belongs to some set of languages; a + keyword is included if language is one of its + languages. + If not set, all keywords will be included. + + This field is a member of `oneof`_ ``_language``. + geo_target_constants (Sequence[str]): + The resource names of the location to target. + Maximum is 10. An empty list MAY be used to + specify all targeting geos. + include_adult_keywords (bool): + If true, adult keywords will be included in + response. The default value is false. + page_token (str): + Token of the page to retrieve. If not specified, the first + page of results will be returned. To request next page of + results use the value obtained from ``next_page_token`` in + the previous response. The request fields must match across + pages. + page_size (int): + Number of results to retrieve in a single page. A maximum of + 10,000 results may be returned, if the page_size exceeds + this, it is ignored. If unspecified, at most 10,000 results + will be returned. The server may decide to further limit the + number of returned resources. If the response contains fewer + than 10,000 results it may not be assumed as last page of + results. + keyword_plan_network (google.ads.googleads.v12.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + Targeting network. + If not set, Google Search And Partners Network + will be used. + keyword_annotation (Sequence[google.ads.googleads.v12.enums.types.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation]): + The keyword annotations to include in + response. + aggregate_metrics (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetrics): + The aggregate fields to include in response. + historical_metrics_options (google.ads.googleads.v12.common.types.HistoricalMetricsOptions): + The options for historical metrics data. + keyword_and_url_seed (google.ads.googleads.v12.services.types.KeywordAndUrlSeed): + A Keyword and a specific Url to generate + ideas from for example, cars, + www.example.com/cars. + + This field is a member of `oneof`_ ``seed``. + keyword_seed (google.ads.googleads.v12.services.types.KeywordSeed): + A Keyword or phrase to generate ideas from, + for example, cars. + + This field is a member of `oneof`_ ``seed``. + url_seed (google.ads.googleads.v12.services.types.UrlSeed): + A specific url to generate ideas from, for + example, www.example.com/cars. + + This field is a member of `oneof`_ ``seed``. + site_seed (google.ads.googleads.v12.services.types.SiteSeed): + The site to generate ideas from, for example, + www.example.com. + + This field is a member of `oneof`_ ``seed``. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + language = proto.Field(proto.STRING, number=14, optional=True,) + geo_target_constants = proto.RepeatedField(proto.STRING, number=15,) + include_adult_keywords = proto.Field(proto.BOOL, number=10,) + page_token = proto.Field(proto.STRING, number=12,) + page_size = proto.Field(proto.INT32, number=13,) + keyword_plan_network = proto.Field( + proto.ENUM, + number=9, + enum=gage_keyword_plan_network.KeywordPlanNetworkEnum.KeywordPlanNetwork, + ) + keyword_annotation = proto.RepeatedField( + proto.ENUM, + number=17, + enum=keyword_plan_keyword_annotation.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation, + ) + aggregate_metrics = proto.Field( + proto.MESSAGE, + number=16, + message=keyword_plan_common.KeywordPlanAggregateMetrics, + ) + historical_metrics_options = proto.Field( + proto.MESSAGE, + number=18, + message=keyword_plan_common.HistoricalMetricsOptions, + ) + keyword_and_url_seed = proto.Field( + proto.MESSAGE, number=2, oneof="seed", message="KeywordAndUrlSeed", + ) + keyword_seed = proto.Field( + proto.MESSAGE, number=3, oneof="seed", message="KeywordSeed", + ) + url_seed = proto.Field( + proto.MESSAGE, number=5, oneof="seed", message="UrlSeed", + ) + site_seed = proto.Field( + proto.MESSAGE, number=11, oneof="seed", message="SiteSeed", + ) + + +class KeywordAndUrlSeed(proto.Message): + r"""Keyword And Url Seed + + Attributes: + url (str): + The URL to crawl in order to generate keyword + ideas. + + This field is a member of `oneof`_ ``_url``. + keywords (Sequence[str]): + Requires at least one keyword. + """ + + url = proto.Field(proto.STRING, number=3, optional=True,) + keywords = proto.RepeatedField(proto.STRING, number=4,) + + +class KeywordSeed(proto.Message): + r"""Keyword Seed + + Attributes: + keywords (Sequence[str]): + Requires at least one keyword. + """ + + keywords = proto.RepeatedField(proto.STRING, number=2,) + + +class SiteSeed(proto.Message): + r"""Site Seed + + Attributes: + site (str): + The domain name of the site. If the customer + requesting the ideas doesn't own the site + provided only public information is returned. + + This field is a member of `oneof`_ ``_site``. + """ + + site = proto.Field(proto.STRING, number=2, optional=True,) + + +class UrlSeed(proto.Message): + r"""Url Seed + + Attributes: + url (str): + The URL to crawl in order to generate keyword + ideas. + + This field is a member of `oneof`_ ``_url``. + """ + + url = proto.Field(proto.STRING, number=2, optional=True,) + + +class GenerateKeywordIdeaResponse(proto.Message): + r"""Response message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.GenerateKeywordIdeaResult]): + Results of generating keyword ideas. + aggregate_metric_results (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetricResults): + The aggregate metrics for all keyword ideas. + next_page_token (str): + Pagination token used to retrieve the next page of results. + Pass the content of this string as the ``page_token`` + attribute of the next request. ``next_page_token`` is not + returned for the last page. + total_size (int): + Total number of results available. + """ + + @property + def raw_page(self): + return self + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="GenerateKeywordIdeaResult", + ) + aggregate_metric_results = proto.Field( + proto.MESSAGE, + number=4, + message=keyword_plan_common.KeywordPlanAggregateMetricResults, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + total_size = proto.Field(proto.INT64, number=3,) + + +class GenerateKeywordIdeaResult(proto.Message): + r"""The result of generating keyword ideas. + + Attributes: + text (str): + Text of the keyword idea. + As in Keyword Plan historical metrics, this text + may not be an actual keyword, but the canonical + form of multiple keywords. See + KeywordPlanKeywordHistoricalMetrics message in + KeywordPlanService. + + This field is a member of `oneof`_ ``_text``. + keyword_idea_metrics (google.ads.googleads.v12.common.types.KeywordPlanHistoricalMetrics): + The historical metrics for the keyword. + keyword_annotations (google.ads.googleads.v12.common.types.KeywordAnnotations): + The annotations for the keyword. + The annotation data is only provided if + requested. + close_variants (Sequence[str]): + The list of close variants from the requested + keywords that are combined into this + GenerateKeywordIdeaResult. See + https://support.google.com/google-ads/answer/9342105 + for the definition of "close variants". + """ + + text = proto.Field(proto.STRING, number=5, optional=True,) + keyword_idea_metrics = proto.Field( + proto.MESSAGE, + number=3, + message=keyword_plan_common.KeywordPlanHistoricalMetrics, + ) + keyword_annotations = proto.Field( + proto.MESSAGE, number=6, message=keyword_plan_common.KeywordAnnotations, + ) + close_variants = proto.RepeatedField(proto.STRING, number=7,) + + +class GenerateKeywordHistoricalMetricsRequest(proto.Message): + r"""Request message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + + Attributes: + customer_id (str): + The ID of the customer with the + recommendation. + keywords (Sequence[str]): + A list of keywords to get historical metrics. + Not all inputs will be returned as a result of + near-exact deduplication. For example, if stats + for "car" and "cars" are requested, only "car" + will be returned. + A maximum of 10,000 keywords can be used. + language (str): + The resource name of the language to target. + Each keyword belongs to some set of languages; a + keyword is included if language is one of its + languages. + If not set, all keywords will be included. + + This field is a member of `oneof`_ ``_language``. + include_adult_keywords (bool): + If true, adult keywords will be included in + response. The default value is false. + geo_target_constants (Sequence[str]): + The resource names of the location to target. + Maximum is 10. An empty list MAY be used to + specify all targeting geos. + keyword_plan_network (google.ads.googleads.v12.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + Targeting network. + If not set, Google Search And Partners Network + will be used. + aggregate_metrics (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetrics): + The aggregate fields to include in response. + historical_metrics_options (google.ads.googleads.v12.common.types.HistoricalMetricsOptions): + The options for historical metrics data. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + keywords = proto.RepeatedField(proto.STRING, number=2,) + language = proto.Field(proto.STRING, number=4, optional=True,) + include_adult_keywords = proto.Field(proto.BOOL, number=5,) + geo_target_constants = proto.RepeatedField(proto.STRING, number=6,) + keyword_plan_network = proto.Field( + proto.ENUM, + number=7, + enum=gage_keyword_plan_network.KeywordPlanNetworkEnum.KeywordPlanNetwork, + ) + aggregate_metrics = proto.Field( + proto.MESSAGE, + number=8, + message=keyword_plan_common.KeywordPlanAggregateMetrics, + ) + historical_metrics_options = proto.Field( + proto.MESSAGE, + number=3, + message=keyword_plan_common.HistoricalMetricsOptions, + ) + + +class GenerateKeywordHistoricalMetricsResponse(proto.Message): + r"""Response message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.GenerateKeywordHistoricalMetricsResult]): + List of keywords and their historical + metrics. + aggregate_metric_results (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetricResults): + The aggregate metrics for all keywords. + """ + + results = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GenerateKeywordHistoricalMetricsResult", + ) + aggregate_metric_results = proto.Field( + proto.MESSAGE, + number=2, + message=keyword_plan_common.KeywordPlanAggregateMetricResults, + ) + + +class GenerateKeywordHistoricalMetricsResult(proto.Message): + r"""The result of generating keyword historical metrics. + + Attributes: + text (str): + The text of the query associated with one or more keywords. + Note that we de-dupe your keywords list, eliminating close + variants before returning the keywords as text. For example, + if your request originally contained the keywords "car" and + "cars", the returned search query will only contain "cars". + The list of de-duped queries will be included in + close_variants field. + + This field is a member of `oneof`_ ``_text``. + close_variants (Sequence[str]): + The list of close variants from the requested + keywords whose stats are combined into this + GenerateKeywordHistoricalMetricsResult. + keyword_metrics (google.ads.googleads.v12.common.types.KeywordPlanHistoricalMetrics): + The historical metrics for text and its close + variants + """ + + text = proto.Field(proto.STRING, number=1, optional=True,) + close_variants = proto.RepeatedField(proto.STRING, number=3,) + keyword_metrics = proto.Field( + proto.MESSAGE, + number=2, + message=keyword_plan_common.KeywordPlanHistoricalMetrics, + ) + + +class GenerateAdGroupThemesRequest(proto.Message): + r"""Request message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + keywords (Sequence[str]): + Required. A list of keywords to group into + the provided AdGroups. + ad_groups (Sequence[str]): + Required. A list of resource names of AdGroups to group + keywords into. Resource name format: + ``customers/{customer_id}/adGroups/{ad_group_id}`` + """ + + customer_id = proto.Field(proto.STRING, number=1,) + keywords = proto.RepeatedField(proto.STRING, number=2,) + ad_groups = proto.RepeatedField(proto.STRING, number=3,) + + +class GenerateAdGroupThemesResponse(proto.Message): + r"""Response message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v12.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + + Attributes: + ad_group_keyword_suggestions (Sequence[google.ads.googleads.v12.services.types.AdGroupKeywordSuggestion]): + A list of suggested AdGroup/keyword pairings. + unusable_ad_groups (Sequence[google.ads.googleads.v12.services.types.UnusableAdGroup]): + A list of provided AdGroups that could not be + used as suggestions. + """ + + ad_group_keyword_suggestions = proto.RepeatedField( + proto.MESSAGE, number=1, message="AdGroupKeywordSuggestion", + ) + unusable_ad_groups = proto.RepeatedField( + proto.MESSAGE, number=2, message="UnusableAdGroup", + ) + + +class AdGroupKeywordSuggestion(proto.Message): + r"""The suggested text and AdGroup/Campaign pairing for a given + keyword. + + Attributes: + keyword_text (str): + The original keyword text. + suggested_keyword_text (str): + The normalized version of keyword_text for + BROAD/EXACT/PHRASE suggestions. + suggested_match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + The suggested keyword match type. + suggested_ad_group (str): + The suggested AdGroup for the keyword. Resource name format: + ``customers/{customer_id}/adGroups/{ad_group_id}`` + suggested_campaign (str): + The suggested Campaign for the keyword. Resource name + format: ``customers/{customer_id}/campaigns/{campaign_id}`` + """ + + keyword_text = proto.Field(proto.STRING, number=1,) + suggested_keyword_text = proto.Field(proto.STRING, number=2,) + suggested_match_type = proto.Field( + proto.ENUM, + number=3, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + suggested_ad_group = proto.Field(proto.STRING, number=4,) + suggested_campaign = proto.Field(proto.STRING, number=5,) + + +class UnusableAdGroup(proto.Message): + r"""An AdGroup/Campaign pair that could not be used as a suggestion for + keywords. + + AdGroups may not be usable if the AdGroup + + - belongs to a Campaign that is not ENABLED or PAUSED + - is itself not ENABLED + + Attributes: + ad_group (str): + The AdGroup resource name. Resource name format: + ``customers/{customer_id}/adGroups/{ad_group_id}`` + campaign (str): + The Campaign resource name. Resource name format: + ``customers/{customer_id}/campaigns/{campaign_id}`` + """ + + ad_group = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_plan_service.py b/google/ads/googleads/v12/services/types/keyword_plan_service.py new file mode 100644 index 000000000..beefacf54 --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_plan_service.py @@ -0,0 +1,541 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import keyword_plan_common +from google.ads.googleads.v12.resources.types import ( + keyword_plan as gagr_keyword_plan, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateKeywordPlansRequest", + "KeywordPlanOperation", + "MutateKeywordPlansResponse", + "MutateKeywordPlansResult", + "GenerateForecastCurveRequest", + "GenerateForecastCurveResponse", + "GenerateForecastTimeSeriesRequest", + "GenerateForecastTimeSeriesResponse", + "GenerateForecastMetricsRequest", + "GenerateForecastMetricsResponse", + "KeywordPlanCampaignForecast", + "KeywordPlanAdGroupForecast", + "KeywordPlanKeywordForecast", + "KeywordPlanCampaignForecastCurve", + "KeywordPlanMaxCpcBidForecastCurve", + "KeywordPlanMaxCpcBidForecast", + "KeywordPlanWeeklyTimeSeriesForecast", + "KeywordPlanWeeklyForecast", + "ForecastMetrics", + "GenerateHistoricalMetricsRequest", + "GenerateHistoricalMetricsResponse", + "KeywordPlanKeywordHistoricalMetrics", + }, +) + + +class MutateKeywordPlansRequest(proto.Message): + r"""Request message for + [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v12.services.KeywordPlanService.MutateKeywordPlans]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + keyword plans are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.KeywordPlanOperation]): + Required. The list of operations to perform + on individual keyword plans. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class KeywordPlanOperation(proto.Message): + r"""A single operation (create, update, remove) on a keyword + plan. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.KeywordPlan): + Create operation: No resource name is + expected for the new keyword plan. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.KeywordPlan): + Update operation: The keyword plan is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed keyword + plan is expected in this format: + + ``customers/{customer_id}/keywordPlans/{keyword_plan_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_keyword_plan.KeywordPlan, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_keyword_plan.KeywordPlan, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateKeywordPlansResponse(proto.Message): + r"""Response message for a keyword plan mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateKeywordPlansResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateKeywordPlansResult", + ) + + +class MutateKeywordPlansResult(proto.Message): + r"""The result for the keyword plan mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class GenerateForecastCurveRequest(proto.Message): + r"""Request message for + [KeywordPlanService.GenerateForecastCurve][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastCurve]. + + Attributes: + keyword_plan (str): + Required. The resource name of the keyword + plan to be forecasted. + """ + + keyword_plan = proto.Field(proto.STRING, number=1,) + + +class GenerateForecastCurveResponse(proto.Message): + r"""Response message for + [KeywordPlanService.GenerateForecastCurve][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastCurve]. + + Attributes: + campaign_forecast_curves (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignForecastCurve]): + List of forecast curves for the keyword plan + campaign. One maximum. + """ + + campaign_forecast_curves = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanCampaignForecastCurve", + ) + + +class GenerateForecastTimeSeriesRequest(proto.Message): + r"""Request message for + [KeywordPlanService.GenerateForecastTimeSeries][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastTimeSeries]. + + Attributes: + keyword_plan (str): + Required. The resource name of the keyword + plan to be forecasted. + """ + + keyword_plan = proto.Field(proto.STRING, number=1,) + + +class GenerateForecastTimeSeriesResponse(proto.Message): + r"""Response message for + [KeywordPlanService.GenerateForecastTimeSeries][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastTimeSeries]. + + Attributes: + weekly_time_series_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanWeeklyTimeSeriesForecast]): + List of weekly time series forecasts for the + keyword plan campaign. One maximum. + """ + + weekly_time_series_forecasts = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanWeeklyTimeSeriesForecast", + ) + + +class GenerateForecastMetricsRequest(proto.Message): + r"""Request message for + [KeywordPlanService.GenerateForecastMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastMetrics]. + + Attributes: + keyword_plan (str): + Required. The resource name of the keyword + plan to be forecasted. + """ + + keyword_plan = proto.Field(proto.STRING, number=1,) + + +class GenerateForecastMetricsResponse(proto.Message): + r"""Response message for + [KeywordPlanService.GenerateForecastMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateForecastMetrics]. + + Attributes: + campaign_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanCampaignForecast]): + List of campaign forecasts. + One maximum. + ad_group_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanAdGroupForecast]): + List of ad group forecasts. + keyword_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanKeywordForecast]): + List of keyword forecasts. + """ + + campaign_forecasts = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanCampaignForecast", + ) + ad_group_forecasts = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanAdGroupForecast", + ) + keyword_forecasts = proto.RepeatedField( + proto.MESSAGE, number=3, message="KeywordPlanKeywordForecast", + ) + + +class KeywordPlanCampaignForecast(proto.Message): + r"""A campaign forecast. + + Attributes: + keyword_plan_campaign (str): + The resource name of the Keyword Plan campaign related to + the forecast. + + ``customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}`` + + This field is a member of `oneof`_ ``_keyword_plan_campaign``. + campaign_forecast (google.ads.googleads.v12.services.types.ForecastMetrics): + The forecast for the Keyword Plan campaign. + """ + + keyword_plan_campaign = proto.Field(proto.STRING, number=3, optional=True,) + campaign_forecast = proto.Field( + proto.MESSAGE, number=2, message="ForecastMetrics", + ) + + +class KeywordPlanAdGroupForecast(proto.Message): + r"""An ad group forecast. + + Attributes: + keyword_plan_ad_group (str): + The resource name of the Keyword Plan ad group related to + the forecast. + + ``customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}`` + + This field is a member of `oneof`_ ``_keyword_plan_ad_group``. + ad_group_forecast (google.ads.googleads.v12.services.types.ForecastMetrics): + The forecast for the Keyword Plan ad group. + """ + + keyword_plan_ad_group = proto.Field(proto.STRING, number=3, optional=True,) + ad_group_forecast = proto.Field( + proto.MESSAGE, number=2, message="ForecastMetrics", + ) + + +class KeywordPlanKeywordForecast(proto.Message): + r"""A keyword forecast. + + Attributes: + keyword_plan_ad_group_keyword (str): + The resource name of the Keyword Plan keyword related to the + forecast. + + ``customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}`` + + This field is a member of `oneof`_ ``_keyword_plan_ad_group_keyword``. + keyword_forecast (google.ads.googleads.v12.services.types.ForecastMetrics): + The forecast for the Keyword Plan keyword. + """ + + keyword_plan_ad_group_keyword = proto.Field( + proto.STRING, number=3, optional=True, + ) + keyword_forecast = proto.Field( + proto.MESSAGE, number=2, message="ForecastMetrics", + ) + + +class KeywordPlanCampaignForecastCurve(proto.Message): + r"""The forecast curve for the campaign. + + Attributes: + keyword_plan_campaign (str): + The resource name of the Keyword Plan campaign related to + the forecast. + + ``customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}`` + + This field is a member of `oneof`_ ``_keyword_plan_campaign``. + max_cpc_bid_forecast_curve (google.ads.googleads.v12.services.types.KeywordPlanMaxCpcBidForecastCurve): + The max cpc bid forecast curve for the + campaign. + """ + + keyword_plan_campaign = proto.Field(proto.STRING, number=3, optional=True,) + max_cpc_bid_forecast_curve = proto.Field( + proto.MESSAGE, number=2, message="KeywordPlanMaxCpcBidForecastCurve", + ) + + +class KeywordPlanMaxCpcBidForecastCurve(proto.Message): + r"""The max cpc bid forecast curve. + + Attributes: + max_cpc_bid_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanMaxCpcBidForecast]): + The forecasts for the Keyword Plan campaign + at different max CPC bids. + """ + + max_cpc_bid_forecasts = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanMaxCpcBidForecast", + ) + + +class KeywordPlanMaxCpcBidForecast(proto.Message): + r"""The forecast of the campaign at a specific bid. + + Attributes: + max_cpc_bid_micros (int): + The max cpc bid in micros. + + This field is a member of `oneof`_ ``_max_cpc_bid_micros``. + max_cpc_bid_forecast (google.ads.googleads.v12.services.types.ForecastMetrics): + The forecast for the Keyword Plan campaign at + the specific bid. + """ + + max_cpc_bid_micros = proto.Field(proto.INT64, number=3, optional=True,) + max_cpc_bid_forecast = proto.Field( + proto.MESSAGE, number=2, message="ForecastMetrics", + ) + + +class KeywordPlanWeeklyTimeSeriesForecast(proto.Message): + r"""The weekly time series forecast for the keyword plan + campaign. + + Attributes: + keyword_plan_campaign (str): + The resource name of the Keyword Plan campaign related to + the forecast. + + ``customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}`` + + This field is a member of `oneof`_ ``_keyword_plan_campaign``. + weekly_forecasts (Sequence[google.ads.googleads.v12.services.types.KeywordPlanWeeklyForecast]): + The forecasts for the Keyword Plan campaign + at different max CPC bids. + """ + + keyword_plan_campaign = proto.Field(proto.STRING, number=1, optional=True,) + weekly_forecasts = proto.RepeatedField( + proto.MESSAGE, number=2, message="KeywordPlanWeeklyForecast", + ) + + +class KeywordPlanWeeklyForecast(proto.Message): + r"""The forecast of the campaign for the week starting start_date. + + Attributes: + start_date (str): + The start date, in yyyy-mm-dd format. This + date is inclusive. + + This field is a member of `oneof`_ ``_start_date``. + forecast (google.ads.googleads.v12.services.types.ForecastMetrics): + The forecast for the Keyword Plan campaign + for the week. + """ + + start_date = proto.Field(proto.STRING, number=1, optional=True,) + forecast = proto.Field(proto.MESSAGE, number=2, message="ForecastMetrics",) + + +class ForecastMetrics(proto.Message): + r"""Forecast metrics. + + Attributes: + impressions (float): + Impressions + + This field is a member of `oneof`_ ``_impressions``. + ctr (float): + Ctr + + This field is a member of `oneof`_ ``_ctr``. + average_cpc (int): + AVG cpc + + This field is a member of `oneof`_ ``_average_cpc``. + clicks (float): + Clicks + + This field is a member of `oneof`_ ``_clicks``. + cost_micros (int): + Cost + + This field is a member of `oneof`_ ``_cost_micros``. + """ + + impressions = proto.Field(proto.DOUBLE, number=7, optional=True,) + ctr = proto.Field(proto.DOUBLE, number=8, optional=True,) + average_cpc = proto.Field(proto.INT64, number=9, optional=True,) + clicks = proto.Field(proto.DOUBLE, number=10, optional=True,) + cost_micros = proto.Field(proto.INT64, number=11, optional=True,) + + +class GenerateHistoricalMetricsRequest(proto.Message): + r"""Request message for + [KeywordPlanService.GenerateHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateHistoricalMetrics]. + + Attributes: + keyword_plan (str): + Required. The resource name of the keyword + plan of which historical metrics are requested. + aggregate_metrics (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetrics): + The aggregate fields to include in response. + historical_metrics_options (google.ads.googleads.v12.common.types.HistoricalMetricsOptions): + The options for historical metrics data. + """ + + keyword_plan = proto.Field(proto.STRING, number=1,) + aggregate_metrics = proto.Field( + proto.MESSAGE, + number=2, + message=keyword_plan_common.KeywordPlanAggregateMetrics, + ) + historical_metrics_options = proto.Field( + proto.MESSAGE, + number=3, + message=keyword_plan_common.HistoricalMetricsOptions, + ) + + +class GenerateHistoricalMetricsResponse(proto.Message): + r"""Response message for + [KeywordPlanService.GenerateHistoricalMetrics][google.ads.googleads.v12.services.KeywordPlanService.GenerateHistoricalMetrics]. + + Attributes: + metrics (Sequence[google.ads.googleads.v12.services.types.KeywordPlanKeywordHistoricalMetrics]): + List of keyword historical metrics. + aggregate_metric_results (google.ads.googleads.v12.common.types.KeywordPlanAggregateMetricResults): + The aggregate metrics for all the keywords in + the keyword planner plan. + """ + + metrics = proto.RepeatedField( + proto.MESSAGE, number=1, message="KeywordPlanKeywordHistoricalMetrics", + ) + aggregate_metric_results = proto.Field( + proto.MESSAGE, + number=2, + message=keyword_plan_common.KeywordPlanAggregateMetricResults, + ) + + +class KeywordPlanKeywordHistoricalMetrics(proto.Message): + r"""A keyword historical metrics. + + Attributes: + search_query (str): + The text of the query associated with one or more + ad_group_keywords in the plan. + + Note that we de-dupe your keywords list, eliminating close + variants before returning the plan's keywords as text. For + example, if your plan originally contained the keywords + 'car' and 'cars', the returned search query will only + contain 'cars'. Starting V5, the list of de-duped queries + will be included in close_variants field. + + This field is a member of `oneof`_ ``_search_query``. + close_variants (Sequence[str]): + The list of close variant queries for search_query whose + search results are combined into the search_query. + keyword_metrics (google.ads.googleads.v12.common.types.KeywordPlanHistoricalMetrics): + The historical metrics for the query associated with one or + more ad_group_keywords in the plan. + """ + + search_query = proto.Field(proto.STRING, number=4, optional=True,) + close_variants = proto.RepeatedField(proto.STRING, number=3,) + keyword_metrics = proto.Field( + proto.MESSAGE, + number=2, + message=keyword_plan_common.KeywordPlanHistoricalMetrics, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/keyword_theme_constant_service.py b/google/ads/googleads/v12/services/types/keyword_theme_constant_service.py new file mode 100644 index 000000000..9d47665ba --- /dev/null +++ b/google/ads/googleads/v12/services/types/keyword_theme_constant_service.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import keyword_theme_constant + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "SuggestKeywordThemeConstantsRequest", + "SuggestKeywordThemeConstantsResponse", + }, +) + + +class SuggestKeywordThemeConstantsRequest(proto.Message): + r"""Request message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v12.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + + Attributes: + query_text (str): + The query text of a keyword theme that will + be used to map to similar keyword themes. For + example, "plumber" or "roofer". + country_code (str): + Upper-case, two-letter country code as + defined by ISO-3166. This for refining the scope + of the query, default to 'US' if not set. + language_code (str): + The two letter language code for get + corresponding keyword theme for refining the + scope of the query, default to 'en' if not set. + """ + + query_text = proto.Field(proto.STRING, number=1,) + country_code = proto.Field(proto.STRING, number=2,) + language_code = proto.Field(proto.STRING, number=3,) + + +class SuggestKeywordThemeConstantsResponse(proto.Message): + r"""Response message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v12.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + + Attributes: + keyword_theme_constants (Sequence[google.ads.googleads.v12.resources.types.KeywordThemeConstant]): + Smart Campaign keyword theme suggestions. + """ + + keyword_theme_constants = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=keyword_theme_constant.KeywordThemeConstant, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/label_service.py b/google/ads/googleads/v12/services/types/label_service.py new file mode 100644 index 000000000..b5be6f2e5 --- /dev/null +++ b/google/ads/googleads/v12/services/types/label_service.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import label as gagr_label +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateLabelsRequest", + "LabelOperation", + "MutateLabelsResponse", + "MutateLabelResult", + }, +) + + +class MutateLabelsRequest(proto.Message): + r"""Request message for + [LabelService.MutateLabels][google.ads.googleads.v12.services.LabelService.MutateLabels]. + + Attributes: + customer_id (str): + Required. ID of the customer whose labels are + being modified. + operations (Sequence[google.ads.googleads.v12.services.types.LabelOperation]): + Required. The list of operations to perform + on labels. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="LabelOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class LabelOperation(proto.Message): + r"""A single operation (create, remove, update) on a label. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.Label): + Create operation: No resource name is + expected for the new label. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.Label): + Update operation: The label is expected to + have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the label being + removed, in this format: + + ``customers/{customer_id}/labels/{label_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=gagr_label.Label, + ) + update = proto.Field( + proto.MESSAGE, number=2, oneof="operation", message=gagr_label.Label, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateLabelsResponse(proto.Message): + r"""Response message for a labels mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateLabelResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateLabelResult", + ) + + +class MutateLabelResult(proto.Message): + r"""The result for a label mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + label (google.ads.googleads.v12.resources.types.Label): + The mutated label with only mutable fields after mutate. The + field will only be returned when response_content_type is + set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + label = proto.Field(proto.MESSAGE, number=2, message=gagr_label.Label,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/media_file_service.py b/google/ads/googleads/v12/services/types/media_file_service.py new file mode 100644 index 000000000..362f76b39 --- /dev/null +++ b/google/ads/googleads/v12/services/types/media_file_service.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + media_file as gagr_media_file, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateMediaFilesRequest", + "MediaFileOperation", + "MutateMediaFilesResponse", + "MutateMediaFileResult", + }, +) + + +class MutateMediaFilesRequest(proto.Message): + r"""Request message for + [MediaFileService.MutateMediaFiles][google.ads.googleads.v12.services.MediaFileService.MutateMediaFiles] + + Attributes: + customer_id (str): + Required. The ID of the customer whose media + files are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.MediaFileOperation]): + Required. The list of operations to perform + on individual media file. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="MediaFileOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class MediaFileOperation(proto.Message): + r"""A single operation to create media file. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + create (google.ads.googleads.v12.resources.types.MediaFile): + Create operation: No resource name is + expected for the new media file. + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_media_file.MediaFile, + ) + + +class MutateMediaFilesResponse(proto.Message): + r"""Response message for a media file mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateMediaFileResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateMediaFileResult", + ) + + +class MutateMediaFileResult(proto.Message): + r"""The result for the media file mutate. + + Attributes: + resource_name (str): + The resource name returned for successful + operations. + media_file (google.ads.googleads.v12.resources.types.MediaFile): + The mutated media file with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + media_file = proto.Field( + proto.MESSAGE, number=2, message=gagr_media_file.MediaFile, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/merchant_center_link_service.py b/google/ads/googleads/v12/services/types/merchant_center_link_service.py new file mode 100644 index 000000000..9cb46160a --- /dev/null +++ b/google/ads/googleads/v12/services/types/merchant_center_link_service.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import merchant_center_link +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "ListMerchantCenterLinksRequest", + "ListMerchantCenterLinksResponse", + "GetMerchantCenterLinkRequest", + "MutateMerchantCenterLinkRequest", + "MerchantCenterLinkOperation", + "MutateMerchantCenterLinkResponse", + "MutateMerchantCenterLinkResult", + }, +) + + +class ListMerchantCenterLinksRequest(proto.Message): + r"""Request message for + [MerchantCenterLinkService.ListMerchantCenterLinks][google.ads.googleads.v12.services.MerchantCenterLinkService.ListMerchantCenterLinks]. + + Attributes: + customer_id (str): + Required. The ID of the customer onto which + to apply the Merchant Center link list + operation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + + +class ListMerchantCenterLinksResponse(proto.Message): + r"""Response message for + [MerchantCenterLinkService.ListMerchantCenterLinks][google.ads.googleads.v12.services.MerchantCenterLinkService.ListMerchantCenterLinks]. + + Attributes: + merchant_center_links (Sequence[google.ads.googleads.v12.resources.types.MerchantCenterLink]): + Merchant Center links available for the + requested customer + """ + + merchant_center_links = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=merchant_center_link.MerchantCenterLink, + ) + + +class GetMerchantCenterLinkRequest(proto.Message): + r"""Request message for + [MerchantCenterLinkService.GetMerchantCenterLink][google.ads.googleads.v12.services.MerchantCenterLinkService.GetMerchantCenterLink]. + + Attributes: + resource_name (str): + Required. Resource name of the Merchant + Center link. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class MutateMerchantCenterLinkRequest(proto.Message): + r"""Request message for + [MerchantCenterLinkService.MutateMerchantCenterLink][google.ads.googleads.v12.services.MerchantCenterLinkService.MutateMerchantCenterLink]. + + Attributes: + customer_id (str): + Required. The ID of the customer being + modified. + operation (google.ads.googleads.v12.services.types.MerchantCenterLinkOperation): + Required. The operation to perform on the + link + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operation = proto.Field( + proto.MESSAGE, number=2, message="MerchantCenterLinkOperation", + ) + validate_only = proto.Field(proto.BOOL, number=3,) + + +class MerchantCenterLinkOperation(proto.Message): + r"""A single update on a Merchant Center link. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + update (google.ads.googleads.v12.resources.types.MerchantCenterLink): + Update operation: The merchant center link is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed merchant + center link is expected, in this format: + + ``customers/{customer_id}/merchantCenterLinks/{merchant_center_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) + update = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=merchant_center_link.MerchantCenterLink, + ) + remove = proto.Field(proto.STRING, number=2, oneof="operation",) + + +class MutateMerchantCenterLinkResponse(proto.Message): + r"""Response message for Merchant Center link mutate. + + Attributes: + result (google.ads.googleads.v12.services.types.MutateMerchantCenterLinkResult): + Result for the mutate. + """ + + result = proto.Field( + proto.MESSAGE, number=2, message="MutateMerchantCenterLinkResult", + ) + + +class MutateMerchantCenterLinkResult(proto.Message): + r"""The result for the Merchant Center link mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/offline_user_data_job_service.py b/google/ads/googleads/v12/services/types/offline_user_data_job_service.py new file mode 100644 index 000000000..2e5be2b47 --- /dev/null +++ b/google/ads/googleads/v12/services/types/offline_user_data_job_service.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import offline_user_data +from google.ads.googleads.v12.resources.types import offline_user_data_job +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "CreateOfflineUserDataJobRequest", + "CreateOfflineUserDataJobResponse", + "RunOfflineUserDataJobRequest", + "AddOfflineUserDataJobOperationsRequest", + "OfflineUserDataJobOperation", + "AddOfflineUserDataJobOperationsResponse", + }, +) + + +class CreateOfflineUserDataJobRequest(proto.Message): + r"""Request message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + + Attributes: + customer_id (str): + Required. The ID of the customer for which to + create an offline user data job. + job (google.ads.googleads.v12.resources.types.OfflineUserDataJob): + Required. The offline user data job to be + created. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + enable_match_rate_range_preview (bool): + If true, match rate range for the offline + user data job is calculated and made available + in the resource. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + job = proto.Field( + proto.MESSAGE, + number=2, + message=offline_user_data_job.OfflineUserDataJob, + ) + validate_only = proto.Field(proto.BOOL, number=3,) + enable_match_rate_range_preview = proto.Field(proto.BOOL, number=5,) + + +class CreateOfflineUserDataJobResponse(proto.Message): + r"""Response message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + + Attributes: + resource_name (str): + The resource name of the OfflineUserDataJob. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class RunOfflineUserDataJobRequest(proto.Message): + r"""Request message for + [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v12.services.OfflineUserDataJobService.RunOfflineUserDataJob]. + + Attributes: + resource_name (str): + Required. The resource name of the + OfflineUserDataJob to run. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + validate_only = proto.Field(proto.BOOL, number=2,) + + +class AddOfflineUserDataJobOperationsRequest(proto.Message): + r"""Request message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v12.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + + Attributes: + resource_name (str): + Required. The resource name of the + OfflineUserDataJob. + enable_partial_failure (bool): + True to enable partial failure for the + offline user data job. + + This field is a member of `oneof`_ ``_enable_partial_failure``. + enable_warnings (bool): + True to enable warnings for the offline user + data job. When enabled, a warning will not block + the OfflineUserDataJobOperation, and will also + return warning messages about malformed field + values. + + This field is a member of `oneof`_ ``_enable_warnings``. + operations (Sequence[google.ads.googleads.v12.services.types.OfflineUserDataJobOperation]): + Required. The list of operations to be done. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + enable_partial_failure = proto.Field(proto.BOOL, number=4, optional=True,) + enable_warnings = proto.Field(proto.BOOL, number=6, optional=True,) + operations = proto.RepeatedField( + proto.MESSAGE, number=3, message="OfflineUserDataJobOperation", + ) + validate_only = proto.Field(proto.BOOL, number=5,) + + +class OfflineUserDataJobOperation(proto.Message): + r"""Operation to be made for the + AddOfflineUserDataJobOperationsRequest. + + 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: + create (google.ads.googleads.v12.common.types.UserData): + Add the provided data to the transaction. + Data cannot be retrieved after being uploaded. + + This field is a member of `oneof`_ ``operation``. + remove (google.ads.googleads.v12.common.types.UserData): + Remove the provided data from the + transaction. Data cannot be retrieved after + being uploaded. + + This field is a member of `oneof`_ ``operation``. + remove_all (bool): + Remove all previously provided data. This is + only supported for Customer Match. + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=offline_user_data.UserData, + ) + remove = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=offline_user_data.UserData, + ) + remove_all = proto.Field(proto.BOOL, number=3, oneof="operation",) + + +class AddOfflineUserDataJobOperationsResponse(proto.Message): + r"""Response message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v12.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + warning (google.rpc.status_pb2.Status): + Non blocking errors that pertain to operation failures in + the warnings mode. Returned only when enable_warnings = + true. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + warning = proto.Field(proto.MESSAGE, number=2, message=status_pb2.Status,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/payments_account_service.py b/google/ads/googleads/v12/services/types/payments_account_service.py new file mode 100644 index 000000000..083faab96 --- /dev/null +++ b/google/ads/googleads/v12/services/types/payments_account_service.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import payments_account + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={"ListPaymentsAccountsRequest", "ListPaymentsAccountsResponse",}, +) + + +class ListPaymentsAccountsRequest(proto.Message): + r"""Request message for fetching all accessible payments + accounts. + + Attributes: + customer_id (str): + Required. The ID of the customer to apply the + PaymentsAccount list operation to. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + + +class ListPaymentsAccountsResponse(proto.Message): + r"""Response message for + [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v12.services.PaymentsAccountService.ListPaymentsAccounts]. + + Attributes: + payments_accounts (Sequence[google.ads.googleads.v12.resources.types.PaymentsAccount]): + The list of accessible payments accounts. + """ + + payments_accounts = proto.RepeatedField( + proto.MESSAGE, number=1, message=payments_account.PaymentsAccount, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/reach_plan_service.py b/google/ads/googleads/v12/services/types/reach_plan_service.py new file mode 100644 index 000000000..9c34244db --- /dev/null +++ b/google/ads/googleads/v12/services/types/reach_plan_service.py @@ -0,0 +1,880 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.common.types import dates +from google.ads.googleads.v12.enums.types import frequency_cap_time_unit +from google.ads.googleads.v12.enums.types import reach_plan_age_range +from google.ads.googleads.v12.enums.types import reach_plan_network + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "ListPlannableLocationsRequest", + "ListPlannableLocationsResponse", + "PlannableLocation", + "ListPlannableProductsRequest", + "ListPlannableProductsResponse", + "ProductMetadata", + "PlannableTargeting", + "GenerateReachForecastRequest", + "EffectiveFrequencyLimit", + "FrequencyCap", + "Targeting", + "CampaignDuration", + "PlannedProduct", + "GenerateReachForecastResponse", + "ReachCurve", + "ReachForecast", + "Forecast", + "PlannedProductReachForecast", + "PlannedProductForecast", + "OnTargetAudienceMetrics", + "EffectiveFrequencyBreakdown", + "ForecastMetricOptions", + "AudienceTargeting", + "AdvancedProductTargeting", + "YouTubeSelectSettings", + "YouTubeSelectLineUp", + }, +) + + +class ListPlannableLocationsRequest(proto.Message): + r"""Request message for + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + + """ + + +class ListPlannableLocationsResponse(proto.Message): + r"""The list of plannable locations. + + Attributes: + plannable_locations (Sequence[google.ads.googleads.v12.services.types.PlannableLocation]): + The list of locations available for planning. + See + https://developers.google.com/google-ads/api/reference/data/geotargets + for sample locations. + """ + + plannable_locations = proto.RepeatedField( + proto.MESSAGE, number=1, message="PlannableLocation", + ) + + +class PlannableLocation(proto.Message): + r"""A plannable location: country, metro region, province, etc. + + Attributes: + id (str): + The location identifier. + + This field is a member of `oneof`_ ``_id``. + name (str): + The unique location name in English. + + This field is a member of `oneof`_ ``_name``. + parent_country_id (int): + The parent country (not present if location is a country). + If present, will always be a GeoTargetConstant ID. + Additional information such as country name is provided by + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations] + or [GoogleAdsService.Search/SearchStream][]. + + This field is a member of `oneof`_ ``_parent_country_id``. + country_code (str): + The ISO-3166-1 alpha-2 country code that is + associated with the location. + + This field is a member of `oneof`_ ``_country_code``. + location_type (str): + The location's type. Location types correspond to + target_type returned by searching location type in + [GoogleAdsService.Search/SearchStream][]. + + This field is a member of `oneof`_ ``_location_type``. + """ + + id = proto.Field(proto.STRING, number=4, optional=True,) + name = proto.Field(proto.STRING, number=5, optional=True,) + parent_country_id = proto.Field(proto.INT64, number=6, optional=True,) + country_code = proto.Field(proto.STRING, number=7, optional=True,) + location_type = proto.Field(proto.STRING, number=8, optional=True,) + + +class ListPlannableProductsRequest(proto.Message): + r"""Request to list available products in a given location. + + Attributes: + plannable_location_id (str): + Required. The ID of the selected location for planning. To + list the available plannable location IDs use + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + """ + + plannable_location_id = proto.Field(proto.STRING, number=2,) + + +class ListPlannableProductsResponse(proto.Message): + r"""A response with all available products. + + Attributes: + product_metadata (Sequence[google.ads.googleads.v12.services.types.ProductMetadata]): + The list of products available for planning + and related targeting metadata. + """ + + product_metadata = proto.RepeatedField( + proto.MESSAGE, number=1, message="ProductMetadata", + ) + + +class ProductMetadata(proto.Message): + r"""The metadata associated with an available plannable product. + + Attributes: + plannable_product_code (str): + The code associated with the ad product (for example: + BUMPER, TRUEVIEW_IN_STREAM). To list the available plannable + product codes use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v12.services.ReachPlanService.ListPlannableProducts]. + + This field is a member of `oneof`_ ``_plannable_product_code``. + plannable_product_name (str): + The name associated with the ad product. + plannable_targeting (google.ads.googleads.v12.services.types.PlannableTargeting): + The allowed plannable targeting for this + product. + """ + + plannable_product_code = proto.Field(proto.STRING, number=4, optional=True,) + plannable_product_name = proto.Field(proto.STRING, number=3,) + plannable_targeting = proto.Field( + proto.MESSAGE, number=2, message="PlannableTargeting", + ) + + +class PlannableTargeting(proto.Message): + r"""The targeting for which traffic metrics will be reported. + + Attributes: + age_ranges (Sequence[google.ads.googleads.v12.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange]): + Allowed plannable age ranges for the product + for which metrics will be reported. Actual + targeting is computed by mapping this age range + onto standard Google common.AgeRangeInfo values. + genders (Sequence[google.ads.googleads.v12.common.types.GenderInfo]): + Targetable genders for the ad product. + devices (Sequence[google.ads.googleads.v12.common.types.DeviceInfo]): + Targetable devices for the ad product. TABLET device + targeting is automatically applied to reported metrics when + MOBILE targeting is selected for CPM_MASTHEAD, + GOOGLE_PREFERRED_BUMPER, and GOOGLE_PREFERRED_SHORT + products. + networks (Sequence[google.ads.googleads.v12.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork]): + Targetable networks for the ad product. + youtube_select_lineups (Sequence[google.ads.googleads.v12.services.types.YouTubeSelectLineUp]): + Targetable YouTube Select Lineups for the ad + product. + """ + + age_ranges = proto.RepeatedField( + proto.ENUM, + number=1, + enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, + ) + genders = proto.RepeatedField( + proto.MESSAGE, number=2, message=criteria.GenderInfo, + ) + devices = proto.RepeatedField( + proto.MESSAGE, number=3, message=criteria.DeviceInfo, + ) + networks = proto.RepeatedField( + proto.ENUM, + number=4, + enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, + ) + youtube_select_lineups = proto.RepeatedField( + proto.MESSAGE, number=5, message="YouTubeSelectLineUp", + ) + + +class GenerateReachForecastRequest(proto.Message): + r"""Request message for + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v12.services.ReachPlanService.GenerateReachForecast]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + currency_code (str): + The currency code. + Three-character ISO 4217 currency code. + + This field is a member of `oneof`_ ``_currency_code``. + campaign_duration (google.ads.googleads.v12.services.types.CampaignDuration): + Required. Campaign duration. + cookie_frequency_cap (int): + Chosen cookie frequency cap to be applied to each planned + product. This is equivalent to the frequency cap exposed in + Google Ads when creating a campaign, it represents the + maximum number of times an ad can be shown to the same user. + If not specified, no cap is applied. + + This field is deprecated in v4 and will eventually be + removed. Use cookie_frequency_cap_setting instead. + + This field is a member of `oneof`_ ``_cookie_frequency_cap``. + cookie_frequency_cap_setting (google.ads.googleads.v12.services.types.FrequencyCap): + Chosen cookie frequency cap to be applied to each planned + product. This is equivalent to the frequency cap exposed in + Google Ads when creating a campaign, it represents the + maximum number of times an ad can be shown to the same user + during a specified time interval. If not specified, a + default of 0 (no cap) is applied. + + This field replaces the deprecated cookie_frequency_cap + field. + min_effective_frequency (int): + Chosen minimum effective frequency (the number of times a + person was exposed to the ad) for the reported reach metrics + [1-10]. This won't affect the targeting, but just the + reporting. If not specified, a default of 1 is applied. + + This field cannot be combined with the + effective_frequency_limit field. + + This field is a member of `oneof`_ ``_min_effective_frequency``. + effective_frequency_limit (google.ads.googleads.v12.services.types.EffectiveFrequencyLimit): + The highest minimum effective frequency (the number of times + a person was exposed to the ad) value [1-10] to include in + Forecast.effective_frequency_breakdowns. If not specified, + Forecast.effective_frequency_breakdowns will not be + provided. + + The effective frequency value provided here will also be + used as the minimum effective frequency for the reported + reach metrics. + + This field cannot be combined with the + min_effective_frequency field. + + This field is a member of `oneof`_ ``_effective_frequency_limit``. + targeting (google.ads.googleads.v12.services.types.Targeting): + The targeting to be applied to all products + selected in the product mix. + This is planned targeting: execution details + might vary based on the advertising product, + consult an implementation specialist. + See specific metrics for details on how + targeting affects them. + planned_products (Sequence[google.ads.googleads.v12.services.types.PlannedProduct]): + Required. The products to be forecast. + The max number of allowed planned products is + 15. + forecast_metric_options (google.ads.googleads.v12.services.types.ForecastMetricOptions): + Controls the forecast metrics returned in the + response. + customer_reach_group (str): + The name of the customer being planned for. This is a + user-defined value. Required if targeting.audience_targeting + is set. + + This field is a member of `oneof`_ ``_customer_reach_group``. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + currency_code = proto.Field(proto.STRING, number=9, optional=True,) + campaign_duration = proto.Field( + proto.MESSAGE, number=3, message="CampaignDuration", + ) + cookie_frequency_cap = proto.Field(proto.INT32, number=10, optional=True,) + cookie_frequency_cap_setting = proto.Field( + proto.MESSAGE, number=8, message="FrequencyCap", + ) + min_effective_frequency = proto.Field( + proto.INT32, number=11, optional=True, + ) + effective_frequency_limit = proto.Field( + proto.MESSAGE, + number=12, + optional=True, + message="EffectiveFrequencyLimit", + ) + targeting = proto.Field(proto.MESSAGE, number=6, message="Targeting",) + planned_products = proto.RepeatedField( + proto.MESSAGE, number=7, message="PlannedProduct", + ) + forecast_metric_options = proto.Field( + proto.MESSAGE, number=13, message="ForecastMetricOptions", + ) + customer_reach_group = proto.Field(proto.STRING, number=14, optional=True,) + + +class EffectiveFrequencyLimit(proto.Message): + r"""Effective frequency limit. + + Attributes: + effective_frequency_breakdown_limit (int): + The highest effective frequency value to include in + Forecast.effective_frequency_breakdowns. This field supports + frequencies 1-10, inclusive. + """ + + effective_frequency_breakdown_limit = proto.Field(proto.INT32, number=1,) + + +class FrequencyCap(proto.Message): + r"""A rule specifying the maximum number of times an ad can be + shown to a user over a particular time period. + + Attributes: + impressions (int): + Required. The number of impressions, + inclusive. + time_unit (google.ads.googleads.v12.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): + Required. The type of time unit. + """ + + impressions = proto.Field(proto.INT32, number=3,) + time_unit = proto.Field( + proto.ENUM, + number=2, + enum=frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit, + ) + + +class Targeting(proto.Message): + r"""The targeting for which traffic metrics will be reported. + + Attributes: + plannable_location_id (str): + The ID of the selected location. Plannable location IDs can + be obtained from + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + + Requests must set either this field or + ``plannable_location_ids``. + + This field is deprecated as of V12 and will be removed in a + future release. Use ``plannable_location_ids`` instead. + + This field is a member of `oneof`_ ``_plannable_location_id``. + plannable_location_ids (Sequence[str]): + The list of plannable location IDs to target with this + forecast. + + If more than one ID is provided, all IDs must have the same + ``parent_country_id``. Planning for more than + ``parent_county`` is not supported. Plannable location IDs + and their ``parent_country_id`` can be obtained from + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v12.services.ReachPlanService.ListPlannableLocations]. + + Requests must set either this field or + ``plannable_location_id``. + age_range (google.ads.googleads.v12.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange): + Targeted age range. + An unset value is equivalent to targeting all + ages. + genders (Sequence[google.ads.googleads.v12.common.types.GenderInfo]): + Targeted genders. + An unset value is equivalent to targeting MALE + and FEMALE. + devices (Sequence[google.ads.googleads.v12.common.types.DeviceInfo]): + Targeted devices. If not specified, targets all applicable + devices. Applicable devices vary by product and region and + can be obtained from + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v12.services.ReachPlanService.ListPlannableProducts]. + network (google.ads.googleads.v12.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork): + Targetable network for the ad product. If not specified, + targets all applicable networks. Applicable networks vary by + product and region and can be obtained from + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v12.services.ReachPlanService.ListPlannableProducts]. + audience_targeting (google.ads.googleads.v12.services.types.AudienceTargeting): + Targeted audiences. + If not specified, does not target any specific + audience. + """ + + plannable_location_id = proto.Field(proto.STRING, number=6, optional=True,) + plannable_location_ids = proto.RepeatedField(proto.STRING, number=8,) + age_range = proto.Field( + proto.ENUM, + number=2, + enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, + ) + genders = proto.RepeatedField( + proto.MESSAGE, number=3, message=criteria.GenderInfo, + ) + devices = proto.RepeatedField( + proto.MESSAGE, number=4, message=criteria.DeviceInfo, + ) + network = proto.Field( + proto.ENUM, + number=5, + enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, + ) + audience_targeting = proto.Field( + proto.MESSAGE, number=7, message="AudienceTargeting", + ) + + +class CampaignDuration(proto.Message): + r"""The duration of a planned campaign. + + Attributes: + duration_in_days (int): + The duration value in days. + + This field cannot be combined with the date_range field. + + This field is a member of `oneof`_ ``_duration_in_days``. + date_range (google.ads.googleads.v12.common.types.DateRange): + Date range of the campaign. Dates are in the yyyy-mm-dd + format and inclusive. The end date must be < 1 year in the + future and the date range must be <= 92 days long. + + This field cannot be combined with the duration_in_days + field. + """ + + duration_in_days = proto.Field(proto.INT32, number=2, optional=True,) + date_range = proto.Field(proto.MESSAGE, number=3, message=dates.DateRange,) + + +class PlannedProduct(proto.Message): + r"""A product being planned for reach. + + Attributes: + plannable_product_code (str): + Required. Selected product for planning. The code associated + with the ad product (for example: Trueview, Bumper). To list + the available plannable product codes use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v12.services.ReachPlanService.ListPlannableProducts]. + + This field is a member of `oneof`_ ``_plannable_product_code``. + budget_micros (int): + Required. Maximum budget allocation in micros for the + selected product. The value is specified in the selected + planning currency_code. For example: 1 000 000$ = 1 000 000 + 000 000 micros. + + This field is a member of `oneof`_ ``_budget_micros``. + advanced_product_targeting (google.ads.googleads.v12.services.types.AdvancedProductTargeting): + Targeting settings for the selected product. To list the + available targeting for each product use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v12.services.ReachPlanService.ListPlannableProducts]. + """ + + plannable_product_code = proto.Field(proto.STRING, number=3, optional=True,) + budget_micros = proto.Field(proto.INT64, number=4, optional=True,) + advanced_product_targeting = proto.Field( + proto.MESSAGE, number=5, message="AdvancedProductTargeting", + ) + + +class GenerateReachForecastResponse(proto.Message): + r"""Response message containing the generated reach curve. + + Attributes: + on_target_audience_metrics (google.ads.googleads.v12.services.types.OnTargetAudienceMetrics): + Reference on target audiences for this curve. + reach_curve (google.ads.googleads.v12.services.types.ReachCurve): + The generated reach curve for the planned + product mix. + """ + + on_target_audience_metrics = proto.Field( + proto.MESSAGE, number=1, message="OnTargetAudienceMetrics", + ) + reach_curve = proto.Field(proto.MESSAGE, number=2, message="ReachCurve",) + + +class ReachCurve(proto.Message): + r"""The reach curve for the planned products. + + Attributes: + reach_forecasts (Sequence[google.ads.googleads.v12.services.types.ReachForecast]): + All points on the reach curve. + """ + + reach_forecasts = proto.RepeatedField( + proto.MESSAGE, number=1, message="ReachForecast", + ) + + +class ReachForecast(proto.Message): + r"""A point on reach curve. + + Attributes: + cost_micros (int): + The cost in micros. + forecast (google.ads.googleads.v12.services.types.Forecast): + Forecasted traffic metrics for this point. + planned_product_reach_forecasts (Sequence[google.ads.googleads.v12.services.types.PlannedProductReachForecast]): + The forecasted allocation and traffic metrics + for each planned product at this point on the + reach curve. + """ + + cost_micros = proto.Field(proto.INT64, number=5,) + forecast = proto.Field(proto.MESSAGE, number=2, message="Forecast",) + planned_product_reach_forecasts = proto.RepeatedField( + proto.MESSAGE, number=4, message="PlannedProductReachForecast", + ) + + +class Forecast(proto.Message): + r"""Forecasted traffic metrics for the planned products and + targeting. + + Attributes: + on_target_reach (int): + Number of unique people reached at least + GenerateReachForecastRequest.min_effective_frequency or + GenerateReachForecastRequest.effective_frequency_limit times + that exactly matches the Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + + This field is a member of `oneof`_ ``_on_target_reach``. + total_reach (int): + Total number of unique people reached at least + GenerateReachForecastRequest.min_effective_frequency or + GenerateReachForecastRequest.effective_frequency_limit + times. This includes people that may fall outside the + specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + + This field is a member of `oneof`_ ``_total_reach``. + on_target_impressions (int): + Number of ad impressions that exactly matches + the Targeting. + + This field is a member of `oneof`_ ``_on_target_impressions``. + total_impressions (int): + Total number of ad impressions. This includes + impressions that may fall outside the specified + Targeting, due to insufficient information on + signed-in users. + + This field is a member of `oneof`_ ``_total_impressions``. + viewable_impressions (int): + Number of times the ad's impressions were + considered viewable. See + https://support.google.com/google-ads/answer/7029393 + for more information about what makes an ad + viewable and how viewability is measured. + + This field is a member of `oneof`_ ``_viewable_impressions``. + effective_frequency_breakdowns (Sequence[google.ads.googleads.v12.services.types.EffectiveFrequencyBreakdown]): + A list of effective frequency forecasts. The list is ordered + starting with 1+ and ending with the value set in + GenerateReachForecastRequest.effective_frequency_limit. If + no effective_frequency_limit was set, this list will be + empty. + on_target_coview_reach (int): + Number of unique people reached that exactly + matches the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_reach``. + total_coview_reach (int): + Number of unique people reached including + co-viewers. This includes people that may fall + outside the specified Targeting. + + This field is a member of `oneof`_ ``_total_coview_reach``. + on_target_coview_impressions (int): + Number of ad impressions that exactly matches + the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_impressions``. + total_coview_impressions (int): + Total number of ad impressions including + co-viewers. This includes impressions that may + fall outside the specified Targeting, due to + insufficient information on signed-in users. + + This field is a member of `oneof`_ ``_total_coview_impressions``. + """ + + on_target_reach = proto.Field(proto.INT64, number=5, optional=True,) + total_reach = proto.Field(proto.INT64, number=6, optional=True,) + on_target_impressions = proto.Field(proto.INT64, number=7, optional=True,) + total_impressions = proto.Field(proto.INT64, number=8, optional=True,) + viewable_impressions = proto.Field(proto.INT64, number=9, optional=True,) + effective_frequency_breakdowns = proto.RepeatedField( + proto.MESSAGE, number=10, message="EffectiveFrequencyBreakdown", + ) + on_target_coview_reach = proto.Field(proto.INT64, number=11, optional=True,) + total_coview_reach = proto.Field(proto.INT64, number=12, optional=True,) + on_target_coview_impressions = proto.Field( + proto.INT64, number=13, optional=True, + ) + total_coview_impressions = proto.Field( + proto.INT64, number=14, optional=True, + ) + + +class PlannedProductReachForecast(proto.Message): + r"""The forecasted allocation and traffic metrics for a specific + product at a point on the reach curve. + + Attributes: + plannable_product_code (str): + Selected product for planning. The product + codes returned are within the set of the ones + returned by ListPlannableProducts when using the + same location ID. + cost_micros (int): + The cost in micros. This may differ from the + product's input allocation if one or more + planned products cannot fulfill the budget + because of limited inventory. + planned_product_forecast (google.ads.googleads.v12.services.types.PlannedProductForecast): + Forecasted traffic metrics for this product. + """ + + plannable_product_code = proto.Field(proto.STRING, number=1,) + cost_micros = proto.Field(proto.INT64, number=2,) + planned_product_forecast = proto.Field( + proto.MESSAGE, number=3, message="PlannedProductForecast", + ) + + +class PlannedProductForecast(proto.Message): + r"""Forecasted traffic metrics for a planned product. + + Attributes: + on_target_reach (int): + Number of unique people reached that exactly matches the + Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + total_reach (int): + Number of unique people reached. This includes people that + may fall outside the specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + on_target_impressions (int): + Number of ad impressions that exactly matches + the Targeting. + total_impressions (int): + Total number of ad impressions. This includes + impressions that may fall outside the specified + Targeting, due to insufficient information on + signed-in users. + viewable_impressions (int): + Number of times the ad's impressions were + considered viewable. See + https://support.google.com/google-ads/answer/7029393 + for more information about what makes an ad + viewable and how viewability is measured. + + This field is a member of `oneof`_ ``_viewable_impressions``. + on_target_coview_reach (int): + Number of unique people reached that exactly + matches the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_reach``. + total_coview_reach (int): + Number of unique people reached including + co-viewers. This includes people that may fall + outside the specified Targeting. + + This field is a member of `oneof`_ ``_total_coview_reach``. + on_target_coview_impressions (int): + Number of ad impressions that exactly matches + the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_impressions``. + total_coview_impressions (int): + Total number of ad impressions including + co-viewers. This includes impressions that may + fall outside the specified Targeting, due to + insufficient information on signed-in users. + + This field is a member of `oneof`_ ``_total_coview_impressions``. + """ + + on_target_reach = proto.Field(proto.INT64, number=1,) + total_reach = proto.Field(proto.INT64, number=2,) + on_target_impressions = proto.Field(proto.INT64, number=3,) + total_impressions = proto.Field(proto.INT64, number=4,) + viewable_impressions = proto.Field(proto.INT64, number=5, optional=True,) + on_target_coview_reach = proto.Field(proto.INT64, number=6, optional=True,) + total_coview_reach = proto.Field(proto.INT64, number=7, optional=True,) + on_target_coview_impressions = proto.Field( + proto.INT64, number=8, optional=True, + ) + total_coview_impressions = proto.Field( + proto.INT64, number=9, optional=True, + ) + + +class OnTargetAudienceMetrics(proto.Message): + r"""Audience metrics for the planned products. + These metrics consider the following targeting dimensions: + - Location + - PlannableAgeRange + - Gender + + Attributes: + youtube_audience_size (int): + Reference audience size matching the + considered targeting for YouTube. + + This field is a member of `oneof`_ ``_youtube_audience_size``. + census_audience_size (int): + Reference audience size matching the + considered targeting for Census. + + This field is a member of `oneof`_ ``_census_audience_size``. + """ + + youtube_audience_size = proto.Field(proto.INT64, number=3, optional=True,) + census_audience_size = proto.Field(proto.INT64, number=4, optional=True,) + + +class EffectiveFrequencyBreakdown(proto.Message): + r"""A breakdown of the number of unique people reached at a given + effective frequency. + + Attributes: + effective_frequency (int): + The effective frequency [1-10]. + on_target_reach (int): + The number of unique people reached at least + effective_frequency times that exactly matches the + Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + total_reach (int): + Total number of unique people reached at least + effective_frequency times. This includes people that may + fall outside the specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + effective_coview_reach (int): + The number of users (including co-viewing users) reached for + the associated effective_frequency value. + + This field is a member of `oneof`_ ``_effective_coview_reach``. + on_target_effective_coview_reach (int): + The number of users (including co-viewing users) reached for + the associated effective_frequency value within the + specified plan demographic. + + This field is a member of `oneof`_ ``_on_target_effective_coview_reach``. + """ + + effective_frequency = proto.Field(proto.INT32, number=1,) + on_target_reach = proto.Field(proto.INT64, number=2,) + total_reach = proto.Field(proto.INT64, number=3,) + effective_coview_reach = proto.Field(proto.INT64, number=4, optional=True,) + on_target_effective_coview_reach = proto.Field( + proto.INT64, number=5, optional=True, + ) + + +class ForecastMetricOptions(proto.Message): + r"""Controls forecast metrics to return. + + Attributes: + include_coview (bool): + Indicates whether to include co-view metrics + in the response forecast. + """ + + include_coview = proto.Field(proto.BOOL, number=1,) + + +class AudienceTargeting(proto.Message): + r"""Audience targeting for reach forecast. + + Attributes: + user_interest (Sequence[google.ads.googleads.v12.common.types.UserInterestInfo]): + List of audiences based on user interests to + be targeted. + """ + + user_interest = proto.RepeatedField( + proto.MESSAGE, number=1, message=criteria.UserInterestInfo, + ) + + +class AdvancedProductTargeting(proto.Message): + r"""Advanced targeting settings for products. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + youtube_select_settings (google.ads.googleads.v12.services.types.YouTubeSelectSettings): + Settings for YouTube Select targeting. + + This field is a member of `oneof`_ ``advanced_targeting``. + """ + + youtube_select_settings = proto.Field( + proto.MESSAGE, + number=1, + oneof="advanced_targeting", + message="YouTubeSelectSettings", + ) + + +class YouTubeSelectSettings(proto.Message): + r"""Request settings for YouTube Select Lineups + + Attributes: + lineup_id (int): + Lineup for YouTube Select Targeting. + """ + + lineup_id = proto.Field(proto.INT64, number=1,) + + +class YouTubeSelectLineUp(proto.Message): + r"""A Plannable YouTube Select Lineup for product targeting. + + Attributes: + lineup_id (int): + The ID of the YouTube Select Lineup. + lineup_name (str): + The unique name of the YouTube Select Lineup. + """ + + lineup_id = proto.Field(proto.INT64, number=1,) + lineup_name = proto.Field(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/recommendation_service.py b/google/ads/googleads/v12/services/types/recommendation_service.py new file mode 100644 index 000000000..cc20ab782 --- /dev/null +++ b/google/ads/googleads/v12/services/types/recommendation_service.py @@ -0,0 +1,612 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import extensions +from google.ads.googleads.v12.enums.types import keyword_match_type +from google.ads.googleads.v12.resources.types import ad as gagr_ad +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "ApplyRecommendationRequest", + "ApplyRecommendationOperation", + "ApplyRecommendationResponse", + "ApplyRecommendationResult", + "DismissRecommendationRequest", + "DismissRecommendationResponse", + }, +) + + +class ApplyRecommendationRequest(proto.Message): + r"""Request message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v12.services.RecommendationService.ApplyRecommendation]. + + Attributes: + customer_id (str): + Required. The ID of the customer with the + recommendation. + operations (Sequence[google.ads.googleads.v12.services.types.ApplyRecommendationOperation]): + Required. The list of operations to apply recommendations. + If partial_failure=false all recommendations should be of + the same type There is a limit of 100 operations per + request. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, operations will be carried out + as a transaction if and only if they are all + valid. Default is false. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="ApplyRecommendationOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + + +class ApplyRecommendationOperation(proto.Message): + r"""Information about the operation to apply a recommendation and + any parameters to customize it. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + The resource name of the recommendation to + apply. + campaign_budget (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.CampaignBudgetParameters): + Optional parameters to use when applying a + campaign budget recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + text_ad (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.TextAdParameters): + Optional parameters to use when applying a + text ad recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + keyword (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.KeywordParameters): + Optional parameters to use when applying + keyword recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + target_cpa_opt_in (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.TargetCpaOptInParameters): + Optional parameters to use when applying + target CPA opt-in recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + target_roas_opt_in (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.TargetRoasOptInParameters): + Optional parameters to use when applying + target ROAS opt-in recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + callout_extension (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.CalloutExtensionParameters): + Parameters to use when applying callout + extension recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + call_extension (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.CallExtensionParameters): + Parameters to use when applying call + extension recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + sitelink_extension (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.SitelinkExtensionParameters): + Parameters to use when applying sitelink + extension recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + move_unused_budget (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.MoveUnusedBudgetParameters): + Parameters to use when applying move unused + budget recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + responsive_search_ad (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.ResponsiveSearchAdParameters): + Parameters to use when applying a responsive + search ad recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + use_broad_match_keyword (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.UseBroadMatchKeywordParameters): + Parameters to use when applying a use broad + match keyword recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + responsive_search_ad_asset (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.ResponsiveSearchAdAssetParameters): + Parameters to use when applying a responsive + search ad asset recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + responsive_search_ad_improve_ad_strength (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.ResponsiveSearchAdImproveAdStrengthParameters): + Parameters to use when applying a responsive + search ad improve ad strength recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + raise_target_cpa_bid_too_low (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.RaiseTargetCpaBidTooLowParameters): + Parameters to use when applying a raise + target CPA bid too low recommendation. The apply + is asynchronous and can take minutes depending + on the number of ad groups there is in the + related campaign. + + This field is a member of `oneof`_ ``apply_parameters``. + forecasting_set_target_roas (google.ads.googleads.v12.services.types.ApplyRecommendationOperation.ForecastingSetTargetRoasParameters): + Parameters to use when applying a forecasting + set target ROAS recommendation. + + This field is a member of `oneof`_ ``apply_parameters``. + """ + + class CampaignBudgetParameters(proto.Message): + r"""Parameters to use when applying a campaign budget + recommendation. + + Attributes: + new_budget_amount_micros (int): + New budget amount to set for target budget + resource. This is a required field. + + This field is a member of `oneof`_ ``_new_budget_amount_micros``. + """ + + new_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class ForecastingSetTargetRoasParameters(proto.Message): + r"""Parameters to use when applying a forecasting set target roas + recommendation. + + Attributes: + target_roas (float): + New target ROAS (revenue per unit of spend) + to set for a campaign resource. + The value is between 0.01 and 1000.0, inclusive. + + This field is a member of `oneof`_ ``_target_roas``. + campaign_budget_amount_micros (int): + New campaign budget amount to set for a + campaign resource. + + This field is a member of `oneof`_ ``_campaign_budget_amount_micros``. + """ + + target_roas = proto.Field(proto.DOUBLE, number=1, optional=True,) + campaign_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class TextAdParameters(proto.Message): + r"""Parameters to use when applying a text ad recommendation. + + Attributes: + ad (google.ads.googleads.v12.resources.types.Ad): + New ad to add to recommended ad group. All + necessary fields need to be set in this message. + This is a required field. + """ + + ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + + class KeywordParameters(proto.Message): + r"""Parameters to use when applying keyword recommendation. + + Attributes: + ad_group (str): + The ad group resource to add keyword to. This + is a required field. + + This field is a member of `oneof`_ ``_ad_group``. + match_type (google.ads.googleads.v12.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + The match type of the keyword. This is a + required field. + cpc_bid_micros (int): + Optional, CPC bid to set for the keyword. If + not set, keyword will use bid based on bidding + strategy used by target ad group. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + """ + + ad_group = proto.Field(proto.STRING, number=4, optional=True,) + match_type = proto.Field( + proto.ENUM, + number=2, + enum=keyword_match_type.KeywordMatchTypeEnum.KeywordMatchType, + ) + cpc_bid_micros = proto.Field(proto.INT64, number=5, optional=True,) + + class TargetCpaOptInParameters(proto.Message): + r"""Parameters to use when applying Target CPA recommendation. + + Attributes: + target_cpa_micros (int): + Average CPA to use for Target CPA bidding + strategy. This is a required field. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + new_campaign_budget_amount_micros (int): + Optional, budget amount to set for the + campaign. + + This field is a member of `oneof`_ ``_new_campaign_budget_amount_micros``. + """ + + target_cpa_micros = proto.Field(proto.INT64, number=3, optional=True,) + new_campaign_budget_amount_micros = proto.Field( + proto.INT64, number=4, optional=True, + ) + + class TargetRoasOptInParameters(proto.Message): + r"""Parameters to use when applying a Target ROAS opt-in + recommendation. + + Attributes: + target_roas (float): + Average ROAS (revenue per unit of spend) to use for Target + ROAS bidding strategy. The value is between 0.01 and 1000.0, + inclusive. This is a required field, unless + new_campaign_budget_amount_micros is set. + + This field is a member of `oneof`_ ``_target_roas``. + new_campaign_budget_amount_micros (int): + Optional, budget amount to set for the + campaign. + + This field is a member of `oneof`_ ``_new_campaign_budget_amount_micros``. + """ + + target_roas = proto.Field(proto.DOUBLE, number=1, optional=True,) + new_campaign_budget_amount_micros = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class CalloutExtensionParameters(proto.Message): + r"""Parameters to use when applying callout extension + recommendation. + + Attributes: + callout_extensions (Sequence[google.ads.googleads.v12.common.types.CalloutFeedItem]): + Callout extensions to be added. This is a + required field. + """ + + callout_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.CalloutFeedItem, + ) + + class CallExtensionParameters(proto.Message): + r"""Parameters to use when applying call extension + recommendation. + + Attributes: + call_extensions (Sequence[google.ads.googleads.v12.common.types.CallFeedItem]): + Call extensions to be added. This is a + required field. + """ + + call_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.CallFeedItem, + ) + + class SitelinkExtensionParameters(proto.Message): + r"""Parameters to use when applying sitelink extension + recommendation. + + Attributes: + sitelink_extensions (Sequence[google.ads.googleads.v12.common.types.SitelinkFeedItem]): + Sitelink extensions to be added. This is a + required field. + """ + + sitelink_extensions = proto.RepeatedField( + proto.MESSAGE, number=1, message=extensions.SitelinkFeedItem, + ) + + class MoveUnusedBudgetParameters(proto.Message): + r"""Parameters to use when applying move unused budget + recommendation. + + Attributes: + budget_micros_to_move (int): + Budget amount to move from excess budget to + constrained budget. This is a required field. + + This field is a member of `oneof`_ ``_budget_micros_to_move``. + """ + + budget_micros_to_move = proto.Field( + proto.INT64, number=2, optional=True, + ) + + class ResponsiveSearchAdAssetParameters(proto.Message): + r"""Parameters to use when applying a responsive search ad asset + recommendation. + + Attributes: + updated_ad (google.ads.googleads.v12.resources.types.Ad): + Updated ad. The current ad's content will be + replaced. + """ + + updated_ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + + class ResponsiveSearchAdImproveAdStrengthParameters(proto.Message): + r"""Parameters to use when applying a responsive search ad + improve ad strength recommendation. + + Attributes: + updated_ad (google.ads.googleads.v12.resources.types.Ad): + Updated ad. The current ad's content will be + replaced. + """ + + updated_ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + + class ResponsiveSearchAdParameters(proto.Message): + r"""Parameters to use when applying a responsive search ad + recommendation. + + Attributes: + ad (google.ads.googleads.v12.resources.types.Ad): + Required. New ad to add to recommended ad + group. + """ + + ad = proto.Field(proto.MESSAGE, number=1, message=gagr_ad.Ad,) + + class RaiseTargetCpaBidTooLowParameters(proto.Message): + r"""Parameters to use when applying a raise target CPA bid too + low recommendation. The apply is asynchronous and can take + minutes depending on the number of ad groups there is in the + related campaign.. + + Attributes: + target_multiplier (float): + Required. A number greater than 1.0 + indicating the factor by which to increase the + target CPA. This is a required field. + """ + + target_multiplier = proto.Field(proto.DOUBLE, number=1,) + + class UseBroadMatchKeywordParameters(proto.Message): + r"""Parameters to use when applying a use broad match keyword + recommendation. + + Attributes: + new_budget_amount_micros (int): + New budget amount to set for target budget + resource. + + This field is a member of `oneof`_ ``_new_budget_amount_micros``. + """ + + new_budget_amount_micros = proto.Field( + proto.INT64, number=1, optional=True, + ) + + resource_name = proto.Field(proto.STRING, number=1,) + campaign_budget = proto.Field( + proto.MESSAGE, + number=2, + oneof="apply_parameters", + message=CampaignBudgetParameters, + ) + text_ad = proto.Field( + proto.MESSAGE, + number=3, + oneof="apply_parameters", + message=TextAdParameters, + ) + keyword = proto.Field( + proto.MESSAGE, + number=4, + oneof="apply_parameters", + message=KeywordParameters, + ) + target_cpa_opt_in = proto.Field( + proto.MESSAGE, + number=5, + oneof="apply_parameters", + message=TargetCpaOptInParameters, + ) + target_roas_opt_in = proto.Field( + proto.MESSAGE, + number=10, + oneof="apply_parameters", + message=TargetRoasOptInParameters, + ) + callout_extension = proto.Field( + proto.MESSAGE, + number=6, + oneof="apply_parameters", + message=CalloutExtensionParameters, + ) + call_extension = proto.Field( + proto.MESSAGE, + number=7, + oneof="apply_parameters", + message=CallExtensionParameters, + ) + sitelink_extension = proto.Field( + proto.MESSAGE, + number=8, + oneof="apply_parameters", + message=SitelinkExtensionParameters, + ) + move_unused_budget = proto.Field( + proto.MESSAGE, + number=9, + oneof="apply_parameters", + message=MoveUnusedBudgetParameters, + ) + responsive_search_ad = proto.Field( + proto.MESSAGE, + number=11, + oneof="apply_parameters", + message=ResponsiveSearchAdParameters, + ) + use_broad_match_keyword = proto.Field( + proto.MESSAGE, + number=12, + oneof="apply_parameters", + message=UseBroadMatchKeywordParameters, + ) + responsive_search_ad_asset = proto.Field( + proto.MESSAGE, + number=13, + oneof="apply_parameters", + message=ResponsiveSearchAdAssetParameters, + ) + responsive_search_ad_improve_ad_strength = proto.Field( + proto.MESSAGE, + number=14, + oneof="apply_parameters", + message=ResponsiveSearchAdImproveAdStrengthParameters, + ) + raise_target_cpa_bid_too_low = proto.Field( + proto.MESSAGE, + number=15, + oneof="apply_parameters", + message=RaiseTargetCpaBidTooLowParameters, + ) + forecasting_set_target_roas = proto.Field( + proto.MESSAGE, + number=16, + oneof="apply_parameters", + message=ForecastingSetTargetRoasParameters, + ) + + +class ApplyRecommendationResponse(proto.Message): + r"""Response message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v12.services.RecommendationService.ApplyRecommendation]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.ApplyRecommendationResult]): + Results of operations to apply + recommendations. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors) we return + the RPC level error. + """ + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message="ApplyRecommendationResult", + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +class ApplyRecommendationResult(proto.Message): + r"""The result of applying a recommendation. + + Attributes: + resource_name (str): + Returned for successful applies. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class DismissRecommendationRequest(proto.Message): + r"""Request message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v12.services.RecommendationService.DismissRecommendation]. + + Attributes: + customer_id (str): + Required. The ID of the customer with the + recommendation. + operations (Sequence[google.ads.googleads.v12.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): + Required. The list of operations to dismiss recommendations. + If partial_failure=false all recommendations should be of + the same type There is a limit of 100 operations per + request. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, operations will be carried in + a single transaction if and only if they are all + valid. Default is false. + """ + + class DismissRecommendationOperation(proto.Message): + r"""Operation to dismiss a single recommendation identified by + resource_name. + + Attributes: + resource_name (str): + The resource name of the recommendation to + dismiss. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=3, message=DismissRecommendationOperation, + ) + partial_failure = proto.Field(proto.BOOL, number=2,) + + +class DismissRecommendationResponse(proto.Message): + r"""Response message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v12.services.RecommendationService.DismissRecommendation]. + + Attributes: + results (Sequence[google.ads.googleads.v12.services.types.DismissRecommendationResponse.DismissRecommendationResult]): + Results of operations to dismiss + recommendations. + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors) we return + the RPC level error. + """ + + class DismissRecommendationResult(proto.Message): + r"""The result of dismissing a recommendation. + + Attributes: + resource_name (str): + Returned for successful dismissals. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + results = proto.RepeatedField( + proto.MESSAGE, number=1, message=DismissRecommendationResult, + ) + partial_failure_error = proto.Field( + proto.MESSAGE, number=2, message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/remarketing_action_service.py b/google/ads/googleads/v12/services/types/remarketing_action_service.py new file mode 100644 index 000000000..34d1ba543 --- /dev/null +++ b/google/ads/googleads/v12/services/types/remarketing_action_service.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import remarketing_action +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateRemarketingActionsRequest", + "RemarketingActionOperation", + "MutateRemarketingActionsResponse", + "MutateRemarketingActionResult", + }, +) + + +class MutateRemarketingActionsRequest(proto.Message): + r"""Request message for + [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v12.services.RemarketingActionService.MutateRemarketingActions]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + remarketing actions are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.RemarketingActionOperation]): + Required. The list of operations to perform + on individual remarketing actions. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="RemarketingActionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class RemarketingActionOperation(proto.Message): + r"""A single operation (create, update) on a remarketing 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: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.RemarketingAction): + Create operation: No resource name is + expected for the new remarketing action. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.RemarketingAction): + Update operation: The remarketing action is + expected to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=remarketing_action.RemarketingAction, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=remarketing_action.RemarketingAction, + ) + + +class MutateRemarketingActionsResponse(proto.Message): + r"""Response message for remarketing action mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateRemarketingActionResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateRemarketingActionResult", + ) + + +class MutateRemarketingActionResult(proto.Message): + r"""The result for the remarketing action mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/shared_criterion_service.py b/google/ads/googleads/v12/services/types/shared_criterion_service.py new file mode 100644 index 000000000..4b16e52ba --- /dev/null +++ b/google/ads/googleads/v12/services/types/shared_criterion_service.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + shared_criterion as gagr_shared_criterion, +) +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateSharedCriteriaRequest", + "SharedCriterionOperation", + "MutateSharedCriteriaResponse", + "MutateSharedCriterionResult", + }, +) + + +class MutateSharedCriteriaRequest(proto.Message): + r"""Request message for + [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v12.services.SharedCriterionService.MutateSharedCriteria]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose shared + criteria are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.SharedCriterionOperation]): + Required. The list of operations to perform + on individual shared criteria. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="SharedCriterionOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class SharedCriterionOperation(proto.Message): + r"""A single operation (create, remove) on an shared criterion. + + 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: + create (google.ads.googleads.v12.resources.types.SharedCriterion): + Create operation: No resource name is + expected for the new shared criterion. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed shared + criterion is expected, in this format: + + ``customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_shared_criterion.SharedCriterion, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateSharedCriteriaResponse(proto.Message): + r"""Response message for a shared criterion mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateSharedCriterionResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateSharedCriterionResult", + ) + + +class MutateSharedCriterionResult(proto.Message): + r"""The result for the shared criterion mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + shared_criterion (google.ads.googleads.v12.resources.types.SharedCriterion): + The mutated shared criterion with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + shared_criterion = proto.Field( + proto.MESSAGE, number=2, message=gagr_shared_criterion.SharedCriterion, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/shared_set_service.py b/google/ads/googleads/v12/services/types/shared_set_service.py new file mode 100644 index 000000000..c1782c64e --- /dev/null +++ b/google/ads/googleads/v12/services/types/shared_set_service.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + shared_set as gagr_shared_set, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateSharedSetsRequest", + "SharedSetOperation", + "MutateSharedSetsResponse", + "MutateSharedSetResult", + }, +) + + +class MutateSharedSetsRequest(proto.Message): + r"""Request message for + [SharedSetService.MutateSharedSets][google.ads.googleads.v12.services.SharedSetService.MutateSharedSets]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose shared + sets are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.SharedSetOperation]): + Required. The list of operations to perform + on individual shared sets. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="SharedSetOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class SharedSetOperation(proto.Message): + r"""A single operation (create, update, remove) on an shared set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.SharedSet): + Create operation: No resource name is + expected for the new shared set. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.SharedSet): + Update operation: The shared set is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed shared set + is expected, in this format: + + ``customers/{customer_id}/sharedSets/{shared_set_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=gagr_shared_set.SharedSet, + ) + update = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=gagr_shared_set.SharedSet, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateSharedSetsResponse(proto.Message): + r"""Response message for a shared set mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateSharedSetResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateSharedSetResult", + ) + + +class MutateSharedSetResult(proto.Message): + r"""The result for the shared set mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + shared_set (google.ads.googleads.v12.resources.types.SharedSet): + The mutated shared set with only mutable fields after + mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + shared_set = proto.Field( + proto.MESSAGE, number=2, message=gagr_shared_set.SharedSet, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/smart_campaign_setting_service.py b/google/ads/googleads/v12/services/types/smart_campaign_setting_service.py new file mode 100644 index 000000000..6d1434b19 --- /dev/null +++ b/google/ads/googleads/v12/services/types/smart_campaign_setting_service.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.enums.types import ( + response_content_type as gage_response_content_type, +) +from google.ads.googleads.v12.resources.types import ( + smart_campaign_setting as gagr_smart_campaign_setting, +) +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateSmartCampaignSettingsRequest", + "SmartCampaignSettingOperation", + "MutateSmartCampaignSettingsResponse", + "MutateSmartCampaignSettingResult", + }, +) + + +class MutateSmartCampaignSettingsRequest(proto.Message): + r"""Request message for + [SmartCampaignSettingService.MutateSmartCampaignSetting][]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose Smart + campaign settings are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.SmartCampaignSettingOperation]): + Required. The list of operations to perform + on individual Smart campaign settings. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + response_content_type (google.ads.googleads.v12.enums.types.ResponseContentTypeEnum.ResponseContentType): + The response content type setting. Determines + whether the mutable resource or just the + resource name should be returned post mutation. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="SmartCampaignSettingOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + response_content_type = proto.Field( + proto.ENUM, + number=5, + enum=gage_response_content_type.ResponseContentTypeEnum.ResponseContentType, + ) + + +class SmartCampaignSettingOperation(proto.Message): + r"""A single operation to update Smart campaign settings for a + campaign. + + Attributes: + update (google.ads.googleads.v12.resources.types.SmartCampaignSetting): + Update operation: The Smart campaign setting + must specify a valid resource name. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + """ + + update = proto.Field( + proto.MESSAGE, + number=1, + message=gagr_smart_campaign_setting.SmartCampaignSetting, + ) + update_mask = proto.Field( + proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask, + ) + + +class MutateSmartCampaignSettingsResponse(proto.Message): + r"""Response message for campaign mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateSmartCampaignSettingResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=1, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateSmartCampaignSettingResult", + ) + + +class MutateSmartCampaignSettingResult(proto.Message): + r"""The result for the Smart campaign setting mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + smart_campaign_setting (google.ads.googleads.v12.resources.types.SmartCampaignSetting): + The mutated Smart campaign setting with only mutable fields + after mutate. The field will only be returned when + response_content_type is set to "MUTABLE_RESOURCE". + """ + + resource_name = proto.Field(proto.STRING, number=1,) + smart_campaign_setting = proto.Field( + proto.MESSAGE, + number=2, + message=gagr_smart_campaign_setting.SmartCampaignSetting, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/smart_campaign_suggest_service.py b/google/ads/googleads/v12/services/types/smart_campaign_suggest_service.py new file mode 100644 index 000000000..e4edc29ad --- /dev/null +++ b/google/ads/googleads/v12/services/types/smart_campaign_suggest_service.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import ad_type_infos +from google.ads.googleads.v12.common.types import criteria +from google.ads.googleads.v12.resources.types import ( + keyword_theme_constant as gagr_keyword_theme_constant, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "SuggestSmartCampaignBudgetOptionsRequest", + "SmartCampaignSuggestionInfo", + "SuggestSmartCampaignBudgetOptionsResponse", + "SuggestSmartCampaignAdRequest", + "SuggestSmartCampaignAdResponse", + "SuggestKeywordThemesRequest", + "SuggestKeywordThemesResponse", + }, +) + + +class SuggestSmartCampaignBudgetOptionsRequest(proto.Message): + r"""Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgets][]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer whose budget + options are to be suggested. + campaign (str): + Required. The resource name of the campaign + to get suggestion for. + + This field is a member of `oneof`_ ``suggestion_data``. + suggestion_info (google.ads.googleads.v12.services.types.SmartCampaignSuggestionInfo): + Required. Information needed to get budget + options + + This field is a member of `oneof`_ ``suggestion_data``. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + campaign = proto.Field(proto.STRING, number=2, oneof="suggestion_data",) + suggestion_info = proto.Field( + proto.MESSAGE, + number=3, + oneof="suggestion_data", + message="SmartCampaignSuggestionInfo", + ) + + +class SmartCampaignSuggestionInfo(proto.Message): + r"""Information needed to get suggestion for Smart Campaign. More + information provided will help the system to derive better + suggestions. + + 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: + final_url (str): + Optional. Landing page URL of the campaign. + language_code (str): + Optional. The two letter advertising language + for the Smart campaign to be constructed, + default to 'en' if not set. + ad_schedules (Sequence[google.ads.googleads.v12.common.types.AdScheduleInfo]): + Optional. The business ad schedule. + keyword_themes (Sequence[google.ads.googleads.v12.common.types.KeywordThemeInfo]): + Optional. Smart campaign keyword themes. This + field may greatly improve suggestion accuracy + and we recommend always setting it if possible. + business_context (google.ads.googleads.v12.services.types.SmartCampaignSuggestionInfo.BusinessContext): + Optional. Context describing the business to + advertise. + + This field is a member of `oneof`_ ``business_setting``. + business_profile_location (str): + Optional. The resource name of a Business Profile location. + Business Profile location resource names can be fetched + through the Business Profile API and adhere to the following + format: ``locations/{locationId}``. + + See the [Business Profile API] + (https://developers.google.com/my-business/reference/businessinformation/rest/v1/accounts.locations) + for additional details. + + This field is a member of `oneof`_ ``business_setting``. + location_list (google.ads.googleads.v12.services.types.SmartCampaignSuggestionInfo.LocationList): + Optional. The targeting geo location by + locations. + + This field is a member of `oneof`_ ``geo_target``. + proximity (google.ads.googleads.v12.common.types.ProximityInfo): + Optional. The targeting geo location by + proximity. + + This field is a member of `oneof`_ ``geo_target``. + """ + + class LocationList(proto.Message): + r"""A list of locations. + + Attributes: + locations (Sequence[google.ads.googleads.v12.common.types.LocationInfo]): + Required. Locations. + """ + + locations = proto.RepeatedField( + proto.MESSAGE, number=1, message=criteria.LocationInfo, + ) + + class BusinessContext(proto.Message): + r"""A context that describes a business. + + Attributes: + business_name (str): + Optional. The name of the business. + """ + + business_name = proto.Field(proto.STRING, number=1,) + + final_url = proto.Field(proto.STRING, number=1,) + language_code = proto.Field(proto.STRING, number=3,) + ad_schedules = proto.RepeatedField( + proto.MESSAGE, number=6, message=criteria.AdScheduleInfo, + ) + keyword_themes = proto.RepeatedField( + proto.MESSAGE, number=7, message=criteria.KeywordThemeInfo, + ) + business_context = proto.Field( + proto.MESSAGE, + number=8, + oneof="business_setting", + message=BusinessContext, + ) + business_profile_location = proto.Field( + proto.STRING, number=9, oneof="business_setting", + ) + location_list = proto.Field( + proto.MESSAGE, number=4, oneof="geo_target", message=LocationList, + ) + proximity = proto.Field( + proto.MESSAGE, + number=5, + oneof="geo_target", + message=criteria.ProximityInfo, + ) + + +class SuggestSmartCampaignBudgetOptionsResponse(proto.Message): + r"""Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgets][]. + Depending on whether the system could suggest the options, either + all of the options or none of them might be returned. + + Attributes: + low (google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + Optional. The lowest budget option. + + This field is a member of `oneof`_ ``_low``. + recommended (google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + Optional. The recommended budget option. + + This field is a member of `oneof`_ ``_recommended``. + high (google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + Optional. The highest budget option. + + This field is a member of `oneof`_ ``_high``. + """ + + class Metrics(proto.Message): + r"""Performance metrics for a given budget option. + + Attributes: + min_daily_clicks (int): + The estimated min daily clicks. + max_daily_clicks (int): + The estimated max daily clicks. + """ + + min_daily_clicks = proto.Field(proto.INT64, number=1,) + max_daily_clicks = proto.Field(proto.INT64, number=2,) + + class BudgetOption(proto.Message): + r"""Smart Campaign budget option. + + Attributes: + daily_amount_micros (int): + The amount of the budget, in the local + currency for the account. Amount is specified in + micros, where one million is equivalent to one + currency unit. + metrics (google.ads.googleads.v12.services.types.SuggestSmartCampaignBudgetOptionsResponse.Metrics): + Metrics pertaining to the suggested budget, + could be empty if there is not enough + information to derive the estimates. + """ + + daily_amount_micros = proto.Field(proto.INT64, number=1,) + metrics = proto.Field( + proto.MESSAGE, + number=2, + message="SuggestSmartCampaignBudgetOptionsResponse.Metrics", + ) + + low = proto.Field( + proto.MESSAGE, number=1, optional=True, message=BudgetOption, + ) + recommended = proto.Field( + proto.MESSAGE, number=2, optional=True, message=BudgetOption, + ) + high = proto.Field( + proto.MESSAGE, number=3, optional=True, message=BudgetOption, + ) + + +class SuggestSmartCampaignAdRequest(proto.Message): + r"""Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + suggestion_info (google.ads.googleads.v12.services.types.SmartCampaignSuggestionInfo): + Required. Inputs used to suggest a Smart campaign ad. + Required fields: final_url, language_code, keyword_themes. + Optional but recommended fields to improve the quality of + the suggestion: business_setting and geo_target. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + suggestion_info = proto.Field( + proto.MESSAGE, number=2, message="SmartCampaignSuggestionInfo", + ) + + +class SuggestSmartCampaignAdResponse(proto.Message): + r"""Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + + Attributes: + ad_info (google.ads.googleads.v12.common.types.SmartCampaignAdInfo): + Optional. Ad info includes 3 creative + headlines and 2 creative descriptions. + """ + + ad_info = proto.Field( + proto.MESSAGE, number=1, message=ad_type_infos.SmartCampaignAdInfo, + ) + + +class SuggestKeywordThemesRequest(proto.Message): + r"""Request message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + suggestion_info (google.ads.googleads.v12.services.types.SmartCampaignSuggestionInfo): + Required. Information to get keyword theme suggestions. + Required fields: + + - suggestion_info.final_url + - suggestion_info.language_code + - suggestion_info.geo_target + + Recommended fields: + + - suggestion_info.business_setting + """ + + customer_id = proto.Field(proto.STRING, number=1,) + suggestion_info = proto.Field( + proto.MESSAGE, number=2, message="SmartCampaignSuggestionInfo", + ) + + +class SuggestKeywordThemesResponse(proto.Message): + r"""Response message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v12.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + + Attributes: + keyword_themes (Sequence[google.ads.googleads.v12.services.types.SuggestKeywordThemesResponse.KeywordTheme]): + Smart campaign keyword theme suggestions. + """ + + class KeywordTheme(proto.Message): + r"""A Smart campaign keyword theme suggestion. + + 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: + keyword_theme_constant (google.ads.googleads.v12.resources.types.KeywordThemeConstant): + A Smart campaign keyword theme constant. + + This field is a member of `oneof`_ ``keyword_theme``. + free_form_keyword_theme (str): + A free-form text keyword theme. + + This field is a member of `oneof`_ ``keyword_theme``. + """ + + keyword_theme_constant = proto.Field( + proto.MESSAGE, + number=1, + oneof="keyword_theme", + message=gagr_keyword_theme_constant.KeywordThemeConstant, + ) + free_form_keyword_theme = proto.Field( + proto.STRING, number=2, oneof="keyword_theme", + ) + + keyword_themes = proto.RepeatedField( + proto.MESSAGE, number=2, message=KeywordTheme, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/third_party_app_analytics_link_service.py b/google/ads/googleads/v12/services/types/third_party_app_analytics_link_service.py new file mode 100644 index 000000000..14487ebc8 --- /dev/null +++ b/google/ads/googleads/v12/services/types/third_party_app_analytics_link_service.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "RegenerateShareableLinkIdRequest", + "RegenerateShareableLinkIdResponse", + }, +) + + +class RegenerateShareableLinkIdRequest(proto.Message): + r"""Request message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v12.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + + Attributes: + resource_name (str): + Resource name of the third party app + analytics link. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +class RegenerateShareableLinkIdResponse(proto.Message): + r"""Response message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v12.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/user_data_service.py b/google/ads/googleads/v12/services/types/user_data_service.py new file mode 100644 index 000000000..f2c0fc213 --- /dev/null +++ b/google/ads/googleads/v12/services/types/user_data_service.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.common.types import offline_user_data + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "UploadUserDataRequest", + "UserDataOperation", + "UploadUserDataResponse", + }, +) + + +class UploadUserDataRequest(proto.Message): + r"""Request message for + [UserDataService.UploadUserData][google.ads.googleads.v12.services.UserDataService.UploadUserData] + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer for which to + update the user data. + operations (Sequence[google.ads.googleads.v12.services.types.UserDataOperation]): + Required. The list of operations to be done. + customer_match_user_list_metadata (google.ads.googleads.v12.common.types.CustomerMatchUserListMetadata): + Metadata for data updates to a Customer Match + user list. + + This field is a member of `oneof`_ ``metadata``. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=3, message="UserDataOperation", + ) + customer_match_user_list_metadata = proto.Field( + proto.MESSAGE, + number=2, + oneof="metadata", + message=offline_user_data.CustomerMatchUserListMetadata, + ) + + +class UserDataOperation(proto.Message): + r"""Operation to be made for the UploadUserDataRequest. + + 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: + create (google.ads.googleads.v12.common.types.UserData): + The list of user data to be appended to the + user list. + + This field is a member of `oneof`_ ``operation``. + remove (google.ads.googleads.v12.common.types.UserData): + The list of user data to be removed from the + user list. + + This field is a member of `oneof`_ ``operation``. + """ + + create = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=offline_user_data.UserData, + ) + remove = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=offline_user_data.UserData, + ) + + +class UploadUserDataResponse(proto.Message): + r"""Response message for + [UserDataService.UploadUserData][google.ads.googleads.v12.services.UserDataService.UploadUserData] + Uploads made through this service will not be visible under the + 'Segment members' section for the Customer Match List in the Google + Ads UI. + + Attributes: + upload_date_time (str): + The date time at which the request was received by API, + formatted as "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + "2019-01-01 12:32:45-08:00". + + This field is a member of `oneof`_ ``_upload_date_time``. + received_operations_count (int): + Number of upload data operations received by + API. + + This field is a member of `oneof`_ ``_received_operations_count``. + """ + + upload_date_time = proto.Field(proto.STRING, number=3, optional=True,) + received_operations_count = proto.Field( + proto.INT32, number=4, optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/services/types/user_list_service.py b/google/ads/googleads/v12/services/types/user_list_service.py new file mode 100644 index 000000000..153064d7a --- /dev/null +++ b/google/ads/googleads/v12/services/types/user_list_service.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.ads.googleads.v12.resources.types import user_list +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v12.services", + marshal="google.ads.googleads.v12", + manifest={ + "MutateUserListsRequest", + "UserListOperation", + "MutateUserListsResponse", + "MutateUserListResult", + }, +) + + +class MutateUserListsRequest(proto.Message): + r"""Request message for + [UserListService.MutateUserLists][google.ads.googleads.v12.services.UserListService.MutateUserLists]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose user + lists are being modified. + operations (Sequence[google.ads.googleads.v12.services.types.UserListOperation]): + Required. The list of operations to perform + on individual user lists. + partial_failure (bool): + If true, successful operations will be + carried out and invalid operations will return + errors. If false, all operations will be carried + out in one transaction if and only if they are + all valid. Default is false. + validate_only (bool): + If true, the request is validated but not + executed. Only errors are returned, not results. + """ + + customer_id = proto.Field(proto.STRING, number=1,) + operations = proto.RepeatedField( + proto.MESSAGE, number=2, message="UserListOperation", + ) + partial_failure = proto.Field(proto.BOOL, number=3,) + validate_only = proto.Field(proto.BOOL, number=4,) + + +class UserListOperation(proto.Message): + r"""A single operation (create, update) on a user list. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v12.resources.types.UserList): + Create operation: No resource name is + expected for the new user list. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v12.resources.types.UserList): + Update operation: The user list is expected + to have a valid resource name. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove operation: A resource name for the removed user list + is expected, in this format: + + ``customers/{customer_id}/userLists/{user_list_id}`` + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask = proto.Field( + proto.MESSAGE, number=4, message=field_mask_pb2.FieldMask, + ) + create = proto.Field( + proto.MESSAGE, number=1, oneof="operation", message=user_list.UserList, + ) + update = proto.Field( + proto.MESSAGE, number=2, oneof="operation", message=user_list.UserList, + ) + remove = proto.Field(proto.STRING, number=3, oneof="operation",) + + +class MutateUserListsResponse(proto.Message): + r"""Response message for user list mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in the partial + failure mode. Returned only when partial_failure = true and + all errors occur inside the operations. If any errors occur + outside the operations (for example, auth errors), we return + an RPC level error. + results (Sequence[google.ads.googleads.v12.services.types.MutateUserListResult]): + All results for the mutate. + """ + + partial_failure_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + results = proto.RepeatedField( + proto.MESSAGE, number=2, message="MutateUserListResult", + ) + + +class MutateUserListResult(proto.Message): + r"""The result for the user list mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name = proto.Field(proto.STRING, number=1,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v12/types/__init__.py b/google/ads/googleads/v12/types/__init__.py new file mode 100644 index 000000000..e8e1c3845 --- /dev/null +++ b/google/ads/googleads/v12/types/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/noxfile.py b/noxfile.py index f3a2c5e97..54171ef3f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -20,9 +20,9 @@ def tests(session): session.install(".") # modules for testing session.install( - "mock>=3.0.0,<4.0.0", - "pyfakefs>=3.5,<3.6", - "coverage==5.5", + "mock>=4.0.3", + "pyfakefs>=3.5,<3.7", + "coverage==6.5.0", ) session.run( "coverage", diff --git a/setup.py b/setup.py index b8eb19fbf..e941d897f 100644 --- a/setup.py +++ b/setup.py @@ -18,14 +18,14 @@ install_requires = [ "google-auth-oauthlib >= 0.3.0, < 1.0.0", - "google-api-core >= 2.8.1, < 3.0.0", + "google-api-core == 2.10.1", "googleapis-common-protos >= 1.56.4, < 2.0.0", # NOTE: Source code for grpcio and grpcio-status exist in the same # grpc/grpc monorepo and thus these two dependencies should always # have the same version range. "grpcio >= 1.38.1, < 2.0.0", "grpcio-status >= 1.38.1, < 2.0.0", - "proto-plus == 1.22.0", + "proto-plus == 1.22.1", "PyYAML >= 5.1, < 7.0", "setuptools >= 40.3.0", "protobuf >= 4.21.5", @@ -36,7 +36,7 @@ setup( name="google-ads", - version="18.1.0", + version="18.2.0", author="Google LLC", author_email="googleapis-packages@google.com", classifiers=[ @@ -53,7 +53,11 @@ python_requires=">=3.7", long_description=long_description, install_requires=install_requires, - extras_require={"tests": ["nox >= 2020.12.31, < 2022.6",]}, + extras_require={ + "tests": [ + "nox >= 2020.12.31, < 2022.6", + ] + }, license="Apache 2.0", packages=find_packages( exclude=["examples", "examples.*", "tests", "tests.*"] diff --git a/tests/fixtures/protobuf_fixture_pb2.py b/tests/fixtures/protobuf_fixture_pb2.py index 023cb812d..09940d328 100644 --- a/tests/fixtures/protobuf_fixture_pb2.py +++ b/tests/fixtures/protobuf_fixture_pb2.py @@ -6,20 +6,23 @@ from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database + # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16protobuf_fixture.proto\"\x1f\n\x0fProtobufFixture\x12\x0c\n\x04name\x18\x01 \x01(\tb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16protobuf_fixture.proto"\x1f\n\x0fProtobufFixture\x12\x0c\n\x04name\x18\x01 \x01(\tb\x06proto3' +) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protobuf_fixture_pb2', globals()) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "protobuf_fixture_pb2", globals() +) if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _PROTOBUFFIXTURE._serialized_start=26 - _PROTOBUFFIXTURE._serialized_end=57 + DESCRIPTOR._options = None + _PROTOBUFFIXTURE._serialized_start = 26 + _PROTOBUFFIXTURE._serialized_end = 57 # @@protoc_insertion_point(module_scope) diff --git a/tests/interceptors/metadata_interceptor_test.py b/tests/interceptors/metadata_interceptor_test.py index b7fbf3c37..886aaef42 100644 --- a/tests/interceptors/metadata_interceptor_test.py +++ b/tests/interceptors/metadata_interceptor_test.py @@ -204,7 +204,10 @@ def test_intercept_updates_user_agent_existing_pb(self): mock_client_call_details.timeout = 5 mock_client_call_details.metadata = [ ("apples", "oranges"), - ("x-goog-api-client", "gl-python/3.7.0 grpc/1.45.0 pb/3.21.0",), + ( + "x-goog-api-client", + "gl-python/3.7.0 grpc/1.45.0 pb/3.21.0", + ), ] # Create a simple function that just returns the client_call_details # so we can make assertions about what was modified in the _intercept